From fef241784ef38c90b4db07d226b9ca06e155c31a Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Sat, 19 Mar 2016 09:13:44 +0100 Subject: [PATCH 01/10] Upload validation --- src/Validation/CommonValidation.php | 16 ++ src/Validation/ImageValidation.php | 16 ++ .../Traits/CommonValidationTrait.php | 75 ++++++++++ .../Traits/ImageValidationTrait.php | 138 ++++++++++++++++++ src/Validation/UploadValidation.php | 19 +++ 5 files changed, 264 insertions(+) create mode 100644 src/Validation/CommonValidation.php create mode 100644 src/Validation/ImageValidation.php create mode 100644 src/Validation/Traits/CommonValidationTrait.php create mode 100644 src/Validation/Traits/ImageValidationTrait.php create mode 100644 src/Validation/UploadValidation.php diff --git a/src/Validation/CommonValidation.php b/src/Validation/CommonValidation.php new file mode 100644 index 00000000..a7cc93ba --- /dev/null +++ b/src/Validation/CommonValidation.php @@ -0,0 +1,16 @@ + 0 && $imgWidth >= $width; + } + + /** + * Check that the file is below the maximum width requirement + * + * @param mixed $check Value to check + * @param int $width Width of Image + * @param bool $requireUpload Whether or not to require a file upload + * @return bool Success + */ + public static function isBelowMaxWidth($check, $width, $requireUpload = true) { + // Optional parameter check if passed or is $context array + $requireUpload = is_array($requireUpload) ? true : $requireUpload; + + $error = (int)Hash::get($check, 'error'); + // Allow circumvention of this rule if uploads is not required + if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { + return true; + } + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + list($imgWidth) = getimagesize($check['tmp_name']); + return $width > 0 && $imgWidth <= $width; + } + + /** + * Check that the file is below the maximum height requirement + * + * @param mixed $check Value to check + * @param int $height Height of Image + * @param bool $requireUpload Whether or not to require a file upload + * @return bool Success + */ + public static function isBelowMaxHeight($check, $height, $requireUpload = true) { + // Optional parameter check if passed or is $context array + $requireUpload = is_array($requireUpload) ? true : $requireUpload; + + $error = (int)Hash::get($check, 'error'); + // Allow circumvention of this rule if uploads is not required + if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { + return true; + } + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + list(, $imgHeight) = getimagesize($check['tmp_name']); + return $height > 0 && $imgHeight <= $height; + } + + /** + * Check that the file is above the minimum height requirement + * + * @param mixed $check Value to check + * @param int $height Height of Image + * @param bool $requireUpload Whether or not to require a file upload + * @return bool Success + */ + public static function isAboveMinHeight($check, $height, $requireUpload = true) { + // Optional parameter check if passed or is $context array + $requireUpload = is_array($requireUpload) ? true : $requireUpload; + + $error = (int)Hash::get($check, 'error'); + // Allow circumvention of this rule if uploads is not required + if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { + return true; + } + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + list(, $imgHeight) = getimagesize($check['tmp_name']); + return $height > 0 && $imgHeight >= $height; + } + + /** + * Check that the file is above the minimum file upload size + * + * @param mixed $check Value to check + * @param int $size Minimum file size + * @param bool $requireUpload Whether or not to require a file upload + * @return bool Success + */ + public static function isAboveMinSize($check, $size, $requireUpload = true) { + // Optional parameter check if passed or is $context array + $requireUpload = is_array($requireUpload) ? true : $requireUpload; + + $error = (int)Hash::get($check, 'error'); + // Allow circumvention of this rule if uploads is not required + if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { + return true; + } + // Non-file uploads also mean the size is too small + if (!isset($check['size']) || !strlen($check['size'])) { + return false; + } + return $check['size'] >= $size; + } +} \ No newline at end of file diff --git a/src/Validation/UploadValidation.php b/src/Validation/UploadValidation.php new file mode 100644 index 00000000..9d628b6d --- /dev/null +++ b/src/Validation/UploadValidation.php @@ -0,0 +1,19 @@ + Date: Sat, 19 Mar 2016 09:16:20 +0100 Subject: [PATCH 02/10] remove default comments --- src/Validation/CommonValidation.php | 6 ------ src/Validation/ImageValidation.php | 6 ------ src/Validation/Traits/CommonValidationTrait.php | 6 ------ src/Validation/Traits/ImageValidationTrait.php | 6 ------ 4 files changed, 24 deletions(-) diff --git a/src/Validation/CommonValidation.php b/src/Validation/CommonValidation.php index a7cc93ba..ef73d7b5 100644 --- a/src/Validation/CommonValidation.php +++ b/src/Validation/CommonValidation.php @@ -1,10 +1,4 @@ Date: Sat, 19 Mar 2016 09:43:14 +0100 Subject: [PATCH 03/10] fix phpcs --- src/Validation/CommonValidation.php | 8 +++---- src/Validation/ImageValidation.php | 8 +++---- .../Traits/CommonValidationTrait.php | 17 +++++++++------ .../Traits/ImageValidationTrait.php | 21 ++++++++++++------- src/Validation/UploadValidation.php | 13 +++--------- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Validation/CommonValidation.php b/src/Validation/CommonValidation.php index ef73d7b5..738610c0 100644 --- a/src/Validation/CommonValidation.php +++ b/src/Validation/CommonValidation.php @@ -2,9 +2,7 @@ namespace Josegonzalez\Upload\Validation; - -class CommonValidation { - +class CommonValidation +{ use CommonValidationTrait; - -} \ No newline at end of file +} diff --git a/src/Validation/ImageValidation.php b/src/Validation/ImageValidation.php index cb15531d..8949efcf 100644 --- a/src/Validation/ImageValidation.php +++ b/src/Validation/ImageValidation.php @@ -2,9 +2,7 @@ namespace Josegonzalez\Upload\Validation; - -class ImageValidation { - +class ImageValidation +{ use ImageValidationTrait; - -} \ No newline at end of file +} diff --git a/src/Validation/Traits/CommonValidationTrait.php b/src/Validation/Traits/CommonValidationTrait.php index dfeb2db1..4a1c67cb 100644 --- a/src/Validation/Traits/CommonValidationTrait.php +++ b/src/Validation/Traits/CommonValidationTrait.php @@ -13,7 +13,8 @@ trait CommonValidationTrait * @param mixed $check Value to check * @return bool Success */ - public static function isUnderPhpSizeLimit($check) { + public static function isUnderPhpSizeLimit($check) + { return Hash::get($check, 'error') !== UPLOAD_ERR_INI_SIZE; } @@ -24,7 +25,8 @@ public static function isUnderPhpSizeLimit($check) { * @param mixed $check Value to check * @return bool Success */ - public static function isUnderFormSizeLimit($check) { + public static function isUnderFormSizeLimit($check) + { return Hash::get($check, 'error') !== UPLOAD_ERR_FORM_SIZE; } @@ -34,7 +36,8 @@ public static function isUnderFormSizeLimit($check) { * @param mixed $check Value to check * @return bool Success */ - public static function isCompletedUpload($check) { + public static function isCompletedUpload($check) + { return Hash::get($check, 'error') !== UPLOAD_ERR_PARTIAL; } @@ -44,7 +47,8 @@ public static function isCompletedUpload($check) { * @param mixed $check Value to check * @return bool Success */ - public static function isFileUpload($check) { + public static function isFileUpload($check) + { return Hash::get($check, 'error') !== UPLOAD_ERR_NO_FILE; } @@ -55,7 +59,8 @@ public static function isFileUpload($check) { * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isSuccessfulWrite($check, $requireUpload = true) { + public static function isSuccessfulWrite($check, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -66,4 +71,4 @@ public static function isSuccessfulWrite($check, $requireUpload = true) { } return $error !== UPLOAD_ERR_CANT_WRITE; } -} \ No newline at end of file +} diff --git a/src/Validation/Traits/ImageValidationTrait.php b/src/Validation/Traits/ImageValidationTrait.php index d3635e38..21353fd0 100644 --- a/src/Validation/Traits/ImageValidationTrait.php +++ b/src/Validation/Traits/ImageValidationTrait.php @@ -4,8 +4,8 @@ use Cake\Utility\Hash; -trait ImageValidationTrait { - +trait ImageValidationTrait +{ /** * Check that the file is above the minimum width requirement * @@ -14,7 +14,8 @@ trait ImageValidationTrait { * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinWidth($check, $width, $requireUpload = true) { + public static function isAboveMinWidth($check, $width, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -39,7 +40,8 @@ public static function isAboveMinWidth($check, $width, $requireUpload = true) { * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isBelowMaxWidth($check, $width, $requireUpload = true) { + public static function isBelowMaxWidth($check, $width, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -64,7 +66,8 @@ public static function isBelowMaxWidth($check, $width, $requireUpload = true) { * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isBelowMaxHeight($check, $height, $requireUpload = true) { + public static function isBelowMaxHeight($check, $height, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -89,7 +92,8 @@ public static function isBelowMaxHeight($check, $height, $requireUpload = true) * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinHeight($check, $height, $requireUpload = true) { + public static function isAboveMinHeight($check, $height, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -114,7 +118,8 @@ public static function isAboveMinHeight($check, $height, $requireUpload = true) * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinSize($check, $size, $requireUpload = true) { + public static function isAboveMinSize($check, $size, $requireUpload = true) + { // Optional parameter check if passed or is $context array $requireUpload = is_array($requireUpload) ? true : $requireUpload; @@ -129,4 +134,4 @@ public static function isAboveMinSize($check, $size, $requireUpload = true) { } return $check['size'] >= $size; } -} \ No newline at end of file +} diff --git a/src/Validation/UploadValidation.php b/src/Validation/UploadValidation.php index 9d628b6d..c5048bee 100644 --- a/src/Validation/UploadValidation.php +++ b/src/Validation/UploadValidation.php @@ -1,19 +1,12 @@ Date: Sun, 20 Mar 2016 17:54:07 +0100 Subject: [PATCH 04/10] add tests --- src/Validation/CommonValidation.php | 2 + src/Validation/ImageValidation.php | 2 + .../Traits/CommonValidationTrait.php | 13 +- .../Traits/ImageValidationTrait.php | 81 ++++-------- .../Validation/CommonValidationTest.php | 57 +++++++++ .../Validation/ImageValidationTest.php | 117 ++++++++++++++++++ 6 files changed, 205 insertions(+), 67 deletions(-) create mode 100644 tests/TestCase/Validation/CommonValidationTest.php create mode 100644 tests/TestCase/Validation/ImageValidationTest.php diff --git a/src/Validation/CommonValidation.php b/src/Validation/CommonValidation.php index 738610c0..8d0902f8 100644 --- a/src/Validation/CommonValidation.php +++ b/src/Validation/CommonValidation.php @@ -2,6 +2,8 @@ namespace Josegonzalez\Upload\Validation; +use Josegonzalez\Upload\Validation\Traits\CommonValidationTrait; + class CommonValidation { use CommonValidationTrait; diff --git a/src/Validation/ImageValidation.php b/src/Validation/ImageValidation.php index 8949efcf..cca67f8a 100644 --- a/src/Validation/ImageValidation.php +++ b/src/Validation/ImageValidation.php @@ -2,6 +2,8 @@ namespace Josegonzalez\Upload\Validation; +use Josegonzalez\Upload\Validation\Traits\ImageValidationTrait; + class ImageValidation { use ImageValidationTrait; diff --git a/src/Validation/Traits/CommonValidationTrait.php b/src/Validation/Traits/CommonValidationTrait.php index 4a1c67cb..5fccfff8 100644 --- a/src/Validation/Traits/CommonValidationTrait.php +++ b/src/Validation/Traits/CommonValidationTrait.php @@ -56,19 +56,10 @@ public static function isFileUpload($check) * Check that the file was successfully written to the server * * @param mixed $check Value to check - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isSuccessfulWrite($check, $requireUpload = true) + public static function isSuccessfulWrite($check) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } - return $error !== UPLOAD_ERR_CANT_WRITE; + return Hash::get($check, 'error') !== UPLOAD_ERR_CANT_WRITE; } } diff --git a/src/Validation/Traits/ImageValidationTrait.php b/src/Validation/Traits/ImageValidationTrait.php index 21353fd0..4f713ff7 100644 --- a/src/Validation/Traits/ImageValidationTrait.php +++ b/src/Validation/Traits/ImageValidationTrait.php @@ -2,8 +2,6 @@ namespace Josegonzalez\Upload\Validation\Traits; -use Cake\Utility\Hash; - trait ImageValidationTrait { /** @@ -11,19 +9,10 @@ trait ImageValidationTrait * * @param mixed $check Value to check * @param int $width Width of Image - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinWidth($check, $width, $requireUpload = true) + public static function isAboveMinWidth($check, $width) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; @@ -37,19 +26,10 @@ public static function isAboveMinWidth($check, $width, $requireUpload = true) * * @param mixed $check Value to check * @param int $width Width of Image - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isBelowMaxWidth($check, $width, $requireUpload = true) + public static function isBelowMaxWidth($check, $width) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; @@ -59,55 +39,37 @@ public static function isBelowMaxWidth($check, $width, $requireUpload = true) } /** - * Check that the file is below the maximum height requirement + * Check that the file is above the minimum height requirement * * @param mixed $check Value to check * @param int $height Height of Image - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isBelowMaxHeight($check, $height, $requireUpload = true) + public static function isAboveMinHeight($check, $height) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; } list(, $imgHeight) = getimagesize($check['tmp_name']); - return $height > 0 && $imgHeight <= $height; + return $height > 0 && $imgHeight >= $height; } /** - * Check that the file is above the minimum height requirement + * Check that the file is below the maximum height requirement * * @param mixed $check Value to check * @param int $height Height of Image - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinHeight($check, $height, $requireUpload = true) + public static function isBelowMaxHeight($check, $height) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; } list(, $imgHeight) = getimagesize($check['tmp_name']); - return $height > 0 && $imgHeight >= $height; + return $height > 0 && $imgHeight <= $height; } /** @@ -115,23 +77,30 @@ public static function isAboveMinHeight($check, $height, $requireUpload = true) * * @param mixed $check Value to check * @param int $size Minimum file size - * @param bool $requireUpload Whether or not to require a file upload * @return bool Success */ - public static function isAboveMinSize($check, $size, $requireUpload = true) + public static function isAboveMinSize($check, $size) { - // Optional parameter check if passed or is $context array - $requireUpload = is_array($requireUpload) ? true : $requireUpload; - - $error = (int)Hash::get($check, 'error'); - // Allow circumvention of this rule if uploads is not required - if (!$requireUpload && $error === UPLOAD_ERR_NO_FILE) { - return true; - } // Non-file uploads also mean the size is too small if (!isset($check['size']) || !strlen($check['size'])) { return false; } return $check['size'] >= $size; } + + /** + * Check that the file is below the maximum file upload size + * + * @param mixed $check Value to check + * @param int $size Maximum file size + * @return bool Success + */ + public function isBelowMaxSize($check, $size) + { + // Non-file uploads also mean the size is too small + if (!isset($check['size']) || !strlen($check['size'])) { + return false; + } + return $check['size'] <= $size; + } } diff --git a/tests/TestCase/Validation/CommonValidationTest.php b/tests/TestCase/Validation/CommonValidationTest.php new file mode 100644 index 00000000..555790eb --- /dev/null +++ b/tests/TestCase/Validation/CommonValidationTest.php @@ -0,0 +1,57 @@ +data = [ + 'name' => 'sample.txt', + 'type' => 'text/plain', + 'tmp_name' => '/tmp/tmpfile', + 'size' => 200 + ]; + } + + public function teardown() + { + parent::tearDown(); + } + + public function testIsUnderPhpSizeLimit() + { + $this->assertTrue(CommonValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(CommonValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_INI_SIZE])); + } + + public function testIsUnderFormSizeLimit() + { + $this->assertTrue(CommonValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(CommonValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_FORM_SIZE])); + } + + public function testIsCompletedUpload() + { + $this->assertTrue(CommonValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(CommonValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_PARTIAL])); + } + + public function testIsFileUpload() + { + $this->assertTrue(CommonValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(CommonValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_NO_FILE])); + } + + public function testIsSuccessfulWrite() + { + $this->assertTrue(CommonValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(CommonValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_CANT_WRITE])); + } +} diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php new file mode 100644 index 00000000..dc35bbc8 --- /dev/null +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -0,0 +1,117 @@ +vfs = new Vfs; + mkdir($this->vfs->path('/tmp')); + + // Write sample image with dimensions: 20x20 + $img = fopen($this->vfs->path('/tmp/tmpimage'), "wb"); + fwrite($img, base64_decode('iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AMUECwX5I9GIwAAACFJREFUOMtj/P//PwM1ARMDlcGogaMGjho4auCogUPFQABpCwMlgqgSYAAAAABJRU5ErkJggg==')); + fclose($img); + + $this->data = [ + 'name' => 'sample.txt', + 'type' => 'text/plain', + 'tmp_name' => $this->vfs->path('/tmp/tmpimage'), + 'size' => 200, + 'error' => UPLOAD_ERR_OK + ]; + } + + public function teardown() + { + parent::tearDown(); + } + + public function testIsAboveMinWidth() + { + $this->assertTrue(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 30)); + + // Test if no tmp_name is set or specified + $this->data['tmp_name'] = ''; + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + + unset($this->data['tmp_name']); + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + } + + public function testIsBelowMaxWidth() + { + $this->assertTrue(ImageValidation::isBelowMaxWidth($this->data, 30)); + $this->assertFalse(ImageValidation::isBelowMaxWidth($this->data, 10)); + + // Test if no tmp_name is set or specified + $this->data['tmp_name'] = ''; + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + + unset($this->data['tmp_name']); + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + } + + public function testIsAboveMinHeight() + { + $this->assertTrue(ImageValidation::isAboveMinHeight($this->data, 10)); + $this->assertFalse(ImageValidation::isAboveMinHeight($this->data, 30)); + + // Test if no tmp_name is set or specified + $this->data['tmp_name'] = ''; + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + + unset($this->data['tmp_name']); + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + } + + public function testIsBelowMaxHeight() + { + $this->assertTrue(ImageValidation::isBelowMaxHeight($this->data, 30)); + $this->assertFalse(ImageValidation::isBelowMaxHeight($this->data, 10)); + + // Test if no tmp_name is set or specified + $this->data['tmp_name'] = ''; + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + + unset($this->data['tmp_name']); + $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + } + + public function testIsAboveMinSize() + { + $this->assertTrue(ImageValidation::isAboveMinSize($this->data, 200)); + $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 250)); + + // Test if no size is set or specified + $this->data['size'] = ''; + $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 200)); + + unset($this->data['size']); + $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 200)); + } + + public function testIsBelowMaxSize() + { + $this->assertTrue(ImageValidation::isBelowMaxSize($this->data, 200)); + $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 150)); + + // Test if no size is set or specified + $this->data['size'] = ''; + $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 200)); + + unset($this->data['size']); + $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 200)); + } +} From 293c0dbf3b4d7ccee299d461066d3fd97baf6bb2 Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Sun, 20 Mar 2016 17:57:37 +0100 Subject: [PATCH 05/10] small fix --- src/Validation/Traits/ImageValidationTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Validation/Traits/ImageValidationTrait.php b/src/Validation/Traits/ImageValidationTrait.php index 4f713ff7..a950ffa1 100644 --- a/src/Validation/Traits/ImageValidationTrait.php +++ b/src/Validation/Traits/ImageValidationTrait.php @@ -95,7 +95,7 @@ public static function isAboveMinSize($check, $size) * @param int $size Maximum file size * @return bool Success */ - public function isBelowMaxSize($check, $size) + public static function isBelowMaxSize($check, $size) { // Non-file uploads also mean the size is too small if (!isset($check['size']) || !strlen($check['size'])) { From ca927c3b7b58a2b70c0359f85465c5b1bba40975 Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Sun, 20 Mar 2016 18:04:42 +0100 Subject: [PATCH 06/10] fix copy-paste errors --- tests/TestCase/Validation/ImageValidationTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index dc35bbc8..dc6323f2 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -57,10 +57,10 @@ public function testIsBelowMaxWidth() // Test if no tmp_name is set or specified $this->data['tmp_name'] = ''; - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isBelowMaxWidth($this->data, 10)); unset($this->data['tmp_name']); - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isBelowMaxWidth($this->data, 10)); } public function testIsAboveMinHeight() @@ -70,10 +70,10 @@ public function testIsAboveMinHeight() // Test if no tmp_name is set or specified $this->data['tmp_name'] = ''; - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isAboveMinHeight($this->data, 10)); unset($this->data['tmp_name']); - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isAboveMinHeight($this->data, 10)); } public function testIsBelowMaxHeight() @@ -83,10 +83,10 @@ public function testIsBelowMaxHeight() // Test if no tmp_name is set or specified $this->data['tmp_name'] = ''; - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isBelowMaxHeight($this->data, 10)); unset($this->data['tmp_name']); - $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 10)); + $this->assertFalse(ImageValidation::isBelowMaxHeight($this->data, 10)); } public function testIsAboveMinSize() From 8287d643d1bb4c35e3b4a70986d8498692796aa7 Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Mon, 21 Mar 2016 18:18:22 +0100 Subject: [PATCH 07/10] docs + some renamings to make the docs more clear + moved minSize and maxSize from ImageValidation to UploadValidation --- docs/validation.rst | 173 ++++++++++++++++++ src/Validation/CommonValidation.php | 10 - src/Validation/DefaultValidation.php | 12 ++ .../Traits/ImageValidationTrait.php | 32 ---- ...ionTrait.php => UploadValidationTrait.php} | 34 +++- src/Validation/UploadValidation.php | 6 +- .../Validation/CommonValidationTest.php | 57 ------ .../Validation/ImageValidationTest.php | 26 --- .../Validation/UploadValidationTest.php | 83 +++++++++ 9 files changed, 303 insertions(+), 130 deletions(-) create mode 100644 docs/validation.rst delete mode 100644 src/Validation/CommonValidation.php create mode 100644 src/Validation/DefaultValidation.php rename src/Validation/Traits/{CommonValidationTrait.php => UploadValidationTrait.php} (61%) delete mode 100644 tests/TestCase/Validation/CommonValidationTest.php create mode 100644 tests/TestCase/Validation/UploadValidationTest.php diff --git a/docs/validation.rst b/docs/validation.rst new file mode 100644 index 00000000..8213104b --- /dev/null +++ b/docs/validation.rst @@ -0,0 +1,173 @@ +Validation +---------- + +By default, no validation rules are loaded or attached to the table. You must +explicitly load the validation provider(s) and attach each rule if needed. + +Installation +^^^^^^^^^^^^ + +This plugin allows you to only load the validation rules that cover you needs. +At this point there are 3 validation providers: + + - UploadValidation (validation rules useful for any upload) + - ImageValidation (validation rules specifically for images) + - DefaultValidation (loads all of the above) + +Since by default, no validation rules are loaded, you should start with that: + +.. code:: php + + provider('upload', \Josegonzalez\Upload\Validation\UploadValidation::class); + // OR + $validator->provider('upload', \Josegonzalez\Upload\Validation\ImageValidation::class); + // OR + $validator->provider('upload', \Josegonzalez\Upload\Validation\DefaultValidation::class); + + ?> + +Afterwards, you can use its rules like: + +.. code:: php + + add('file', 'filePhpUploadSize', [ + 'rule' => 'nameOfTheRule', + 'message' => 'yourErrorMessage', + 'provider' => 'upload' + ]); + + ?> + + +UploadValidation +^^^^^^^^^^^^^^^^ + +**isUnderPhpSizeLimit** + +Check that the file does not exceed the max file size specified by PHP + +**isUnderFormSizeLimit** + +Check that the file does not exceed the max file size specified in the +HTML Form + +**isCompletedUpload** + +Check that the file was completely uploaded + +**isFileUpload** + +Check that a file was uploaded + +**isSuccessfulWrite** + +Check that the file was successfully written to the server + +**isBelowMaxSize** + +Check that the file is below the maximum file upload size (checked in +bytes) + +.. code:: php + + add('file', 'fileBelowMaxSize', [ + 'rule' => ['isBelowMaxSize', 1024], + 'message' => 'This file is too large', + 'provider' => 'upload' + ]); + + ?> + +**isAboveMinSize** + +Check that the file is above the minimum file upload size (checked in +bytes) + +.. code:: php + + add('file', 'fileAboveMinSize', [ + 'rule' => ['isAboveMinSize', 1024], + 'message' => 'This file is too small', + 'provider' => 'upload' + ]); + + ?> + +ImageValidation +^^^^^^^^^^^^^^^ + +**isAboveMinHeight** + +Check that the file is above the minimum height requirement (checked in +pixels) + +.. code:: php + + add('file', 'fileAboveMinHeight', [ + 'rule' => ['isAboveMinHeight', 200], + 'message' => 'This image should at least be 200px high', + 'provider' => 'upload' + ]); + + ?> + +**isBelowMaxHeight** + +Check that the file is below the maximum height requirement (checked in +pixels) + +.. code:: php + + add('file', 'fileBelowMaxHeight', [ + 'rule' => ['isBelowMaxHeight', 200], + 'message' => 'This image should not be higher than 200px', + 'provider' => 'upload' + ]); + + ?> + +**isAboveMinWidth** + +Check that the file is above the minimum width requirement (checked in +pixels) + +.. code:: php + + add('file', 'fileAboveMinWidth', [ + 'rule' => ['isAboveMinWidth', 200], + 'message' => 'This image should at least be 200px wide', + 'provider' => 'upload' + ]); + + ?> + +**isBelowMaxWidth** + +Check that the file is below the maximum width requirement (checked in +pixels) + +.. code:: php + + add('file', 'fileBelowMaxWidth', [ + 'rule' => ['isBelowMaxWidth', 200], + 'message' => 'This image should not be wider than 200px', + 'provider' => 'upload' + ]); + + ?> diff --git a/src/Validation/CommonValidation.php b/src/Validation/CommonValidation.php deleted file mode 100644 index 8d0902f8..00000000 --- a/src/Validation/CommonValidation.php +++ /dev/null @@ -1,10 +0,0 @@ - 0 && $imgHeight <= $height; } - - /** - * Check that the file is above the minimum file upload size - * - * @param mixed $check Value to check - * @param int $size Minimum file size - * @return bool Success - */ - public static function isAboveMinSize($check, $size) - { - // Non-file uploads also mean the size is too small - if (!isset($check['size']) || !strlen($check['size'])) { - return false; - } - return $check['size'] >= $size; - } - - /** - * Check that the file is below the maximum file upload size - * - * @param mixed $check Value to check - * @param int $size Maximum file size - * @return bool Success - */ - public static function isBelowMaxSize($check, $size) - { - // Non-file uploads also mean the size is too small - if (!isset($check['size']) || !strlen($check['size'])) { - return false; - } - return $check['size'] <= $size; - } } diff --git a/src/Validation/Traits/CommonValidationTrait.php b/src/Validation/Traits/UploadValidationTrait.php similarity index 61% rename from src/Validation/Traits/CommonValidationTrait.php rename to src/Validation/Traits/UploadValidationTrait.php index 5fccfff8..9392be85 100644 --- a/src/Validation/Traits/CommonValidationTrait.php +++ b/src/Validation/Traits/UploadValidationTrait.php @@ -4,7 +4,7 @@ use Cake\Utility\Hash; -trait CommonValidationTrait +trait UploadValidationTrait { /** * Check that the file does not exceed the max @@ -62,4 +62,36 @@ public static function isSuccessfulWrite($check) { return Hash::get($check, 'error') !== UPLOAD_ERR_CANT_WRITE; } + + /** + * Check that the file is above the minimum file upload size + * + * @param mixed $check Value to check + * @param int $size Minimum file size + * @return bool Success + */ + public static function isAboveMinSize($check, $size) + { + // Non-file uploads also mean the size is too small + if (!isset($check['size']) || !strlen($check['size'])) { + return false; + } + return $check['size'] >= $size; + } + + /** + * Check that the file is below the maximum file upload size + * + * @param mixed $check Value to check + * @param int $size Maximum file size + * @return bool Success + */ + public static function isBelowMaxSize($check, $size) + { + // Non-file uploads also mean the size is too small + if (!isset($check['size']) || !strlen($check['size'])) { + return false; + } + return $check['size'] <= $size; + } } diff --git a/src/Validation/UploadValidation.php b/src/Validation/UploadValidation.php index c5048bee..a4408065 100644 --- a/src/Validation/UploadValidation.php +++ b/src/Validation/UploadValidation.php @@ -2,11 +2,9 @@ namespace Josegonzalez\Upload\Validation; -use Josegonzalez\Upload\Validation\Traits\CommonValidationTrait; -use Josegonzalez\Upload\Validation\Traits\ImageValidationTrait; +use Josegonzalez\Upload\Validation\Traits\UploadValidationTrait; class UploadValidation { - use CommonValidationTrait; - use ImageValidationTrait; + use UploadValidationTrait; } diff --git a/tests/TestCase/Validation/CommonValidationTest.php b/tests/TestCase/Validation/CommonValidationTest.php deleted file mode 100644 index 555790eb..00000000 --- a/tests/TestCase/Validation/CommonValidationTest.php +++ /dev/null @@ -1,57 +0,0 @@ -data = [ - 'name' => 'sample.txt', - 'type' => 'text/plain', - 'tmp_name' => '/tmp/tmpfile', - 'size' => 200 - ]; - } - - public function teardown() - { - parent::tearDown(); - } - - public function testIsUnderPhpSizeLimit() - { - $this->assertTrue(CommonValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); - $this->assertFalse(CommonValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_INI_SIZE])); - } - - public function testIsUnderFormSizeLimit() - { - $this->assertTrue(CommonValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); - $this->assertFalse(CommonValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_FORM_SIZE])); - } - - public function testIsCompletedUpload() - { - $this->assertTrue(CommonValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_OK])); - $this->assertFalse(CommonValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_PARTIAL])); - } - - public function testIsFileUpload() - { - $this->assertTrue(CommonValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_OK])); - $this->assertFalse(CommonValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_NO_FILE])); - } - - public function testIsSuccessfulWrite() - { - $this->assertTrue(CommonValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_OK])); - $this->assertFalse(CommonValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_CANT_WRITE])); - } -} diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index dc6323f2..964ac8b4 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -88,30 +88,4 @@ public function testIsBelowMaxHeight() unset($this->data['tmp_name']); $this->assertFalse(ImageValidation::isBelowMaxHeight($this->data, 10)); } - - public function testIsAboveMinSize() - { - $this->assertTrue(ImageValidation::isAboveMinSize($this->data, 200)); - $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 250)); - - // Test if no size is set or specified - $this->data['size'] = ''; - $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 200)); - - unset($this->data['size']); - $this->assertFalse(ImageValidation::isAboveMinSize($this->data, 200)); - } - - public function testIsBelowMaxSize() - { - $this->assertTrue(ImageValidation::isBelowMaxSize($this->data, 200)); - $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 150)); - - // Test if no size is set or specified - $this->data['size'] = ''; - $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 200)); - - unset($this->data['size']); - $this->assertFalse(ImageValidation::isBelowMaxSize($this->data, 200)); - } } diff --git a/tests/TestCase/Validation/UploadValidationTest.php b/tests/TestCase/Validation/UploadValidationTest.php new file mode 100644 index 00000000..cfa0c627 --- /dev/null +++ b/tests/TestCase/Validation/UploadValidationTest.php @@ -0,0 +1,83 @@ +data = [ + 'name' => 'sample.txt', + 'type' => 'text/plain', + 'tmp_name' => '/tmp/tmpfile', + 'size' => 200 + ]; + } + + public function teardown() + { + parent::tearDown(); + } + + public function testIsUnderPhpSizeLimit() + { + $this->assertTrue(UploadValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(UploadValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_INI_SIZE])); + } + + public function testIsUnderFormSizeLimit() + { + $this->assertTrue(UploadValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(UploadValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_FORM_SIZE])); + } + + public function testIsCompletedUpload() + { + $this->assertTrue(UploadValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(UploadValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_PARTIAL])); + } + + public function testIsFileUpload() + { + $this->assertTrue(UploadValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(UploadValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_NO_FILE])); + } + + public function testIsSuccessfulWrite() + { + $this->assertTrue(UploadValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_OK])); + $this->assertFalse(UploadValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_CANT_WRITE])); + } + + public function testIsAboveMinSize() + { + $this->assertTrue(UploadValidation::isAboveMinSize($this->data, 200)); + $this->assertFalse(UploadValidation::isAboveMinSize($this->data, 250)); + + // Test if no size is set or specified + $this->data['size'] = ''; + $this->assertFalse(UploadValidation::isAboveMinSize($this->data, 200)); + + unset($this->data['size']); + $this->assertFalse(UploadValidation::isAboveMinSize($this->data, 200)); + } + + public function testIsBelowMaxSize() + { + $this->assertTrue(UploadValidation::isBelowMaxSize($this->data, 200)); + $this->assertFalse(UploadValidation::isBelowMaxSize($this->data, 150)); + + // Test if no size is set or specified + $this->data['size'] = ''; + $this->assertFalse(UploadValidation::isBelowMaxSize($this->data, 200)); + + unset($this->data['size']); + $this->assertFalse(UploadValidation::isBelowMaxSize($this->data, 200)); + } +} From e9cbbae87d9e70dc0627db7aa103a1a4cdf5e25b Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Mon, 21 Mar 2016 18:27:45 +0100 Subject: [PATCH 08/10] fix phpcs + add validation to doc index --- docs/index.rst | 1 + src/Validation/DefaultValidation.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 371b4c2c..48daa706 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,7 @@ Contents: Installation Examples Configuration options + Validation Upload Behavior Interfaces diff --git a/src/Validation/DefaultValidation.php b/src/Validation/DefaultValidation.php index 27a0fda4..64601af5 100644 --- a/src/Validation/DefaultValidation.php +++ b/src/Validation/DefaultValidation.php @@ -2,11 +2,11 @@ namespace Josegonzalez\Upload\Validation; -use Josegonzalez\Upload\Validation\Traits\UploadValidationTrait; use Josegonzalez\Upload\Validation\Traits\ImageValidationTrait; +use Josegonzalez\Upload\Validation\Traits\UploadValidationTrait; class DefaultValidation { - use UploadValidationTrait; use ImageValidationTrait; + use UploadValidationTrait; } From cb91a6fe97ea606b3cb7e4e979acaec6a1f8bad2 Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Mon, 21 Mar 2016 18:46:48 +0100 Subject: [PATCH 09/10] more validation examples --- docs/validation.rst | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/validation.rst b/docs/validation.rst index 8213104b..1d836cba 100644 --- a/docs/validation.rst +++ b/docs/validation.rst @@ -50,23 +50,83 @@ UploadValidation Check that the file does not exceed the max file size specified by PHP +.. code:: php + + add('file', 'fileUnderPhpSizeLimit', [ + 'rule' => 'isUnderPhpSizeLimit', + 'message' => 'This file is too large', + 'provider' => 'upload' + ]); + + ?> + **isUnderFormSizeLimit** Check that the file does not exceed the max file size specified in the HTML Form +.. code:: php + + add('file', 'fileUnderFormSizeLimit', [ + 'rule' => 'isUnderFormSizeLimit', + 'message' => 'This file is too large', + 'provider' => 'upload' + ]); + + ?> + **isCompletedUpload** Check that the file was completely uploaded +.. code:: php + + add('file', 'fileCompletedUpload', [ + 'rule' => 'isCompletedUpload', + 'message' => 'This file could not be uploaded completely', + 'provider' => 'upload' + ]); + + ?> + **isFileUpload** Check that a file was uploaded +.. code:: php + + add('file', 'fileFileUpload', [ + 'rule' => 'isFileUpload', + 'message' => 'There was no file found to upload', + 'provider' => 'upload' + ]); + + ?> + **isSuccessfulWrite** Check that the file was successfully written to the server +.. code:: php + + add('file', 'fileSuccessfulWrite', [ + 'rule' => 'isSuccessfulWrite', + 'message' => 'This upload failed', + 'provider' => 'upload' + ]); + + ?> + **isBelowMaxSize** Check that the file is below the maximum file upload size (checked in From 4911745fac76cc104dd63037ece78f5dfad3d221 Mon Sep 17 00:00:00 2001 From: Joris Vaesen Date: Mon, 21 Mar 2016 20:29:08 +0100 Subject: [PATCH 10/10] update doc with conditional validation --- docs/validation.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/validation.rst b/docs/validation.rst index 1d836cba..3f9f9659 100644 --- a/docs/validation.rst +++ b/docs/validation.rst @@ -34,7 +34,7 @@ Afterwards, you can use its rules like: add('file', 'filePhpUploadSize', [ + $validator->add('file', 'customName', [ 'rule' => 'nameOfTheRule', 'message' => 'yourErrorMessage', 'provider' => 'upload' @@ -42,7 +42,25 @@ Afterwards, you can use its rules like: ?> +It might come in handy to only use a validation rule when there actually is an uploaded file: +.. code:: php + + add('file', 'customName', [ + 'rule' => 'nameOfTheRule', + 'message' => 'yourErrorMessage', + 'provider' => 'upload', + 'on' => function($context) { + return isset($context['data']['file']) && $context['data']['file']['error'] == UPLOAD_ERR_OK; + } + ]); + + ?> + +More information on conditional validation can be found `here `__. + UploadValidation ^^^^^^^^^^^^^^^^