Skip to content

Commit 01626de

Browse files
authored
Merge pull request #69 from rakit/split-uploaded-file
Improve uploaded file validation
2 parents 12d06ff + 0e249b9 commit 01626de

21 files changed

+489
-73
lines changed

README.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ Below is list of all available validation rules
269269
* [required_without](#rule-required_without)
270270
* [required_with_all](#rule-required_with_all)
271271
* [required_without_all](#rule-required_without_all)
272-
* [uploaded_file](#rule-uploaded_file)
272+
* [uploaded_file](#rule-uploaded_file) (uploaded file)
273+
* [mimes](#rule-mimes) (uploaded file)
273274
* [default/defaults](#rule-default)
274275
* [email](#rule-email)
275276
* [uppercase](#rule-uppercase)
@@ -355,7 +356,7 @@ The field under validation must be present and not empty only if all of the othe
355356
The field under validation must be present and not empty only when all of the other specified fields are not present.
356357

357358
<a id="rule-uploaded_file"></a>
358-
#### uploaded_file:min_size,max_size,file_type_a,file_type_b,...
359+
#### uploaded_file:min_size,max_size,extension_a,extension_b,...
359360

360361
This rule will validate `$_FILES` data, but not for multiple uploaded files.
361362
Field under this rule must be following rules below to be valid:
@@ -372,6 +373,12 @@ Here are some example definitions and explanations:
372373
* `uploaded_file:0,1M`: uploaded file size must be between 0 - 1 MB, but uploaded file is optional.
373374
* `required|uploaded_file:0,1M,png,jpeg`: uploaded file size must be between 0 - 1MB and mime types must be `image/jpeg` or `image/png`.
374375

376+
377+
<a id="rule-default"></a>
378+
#### mimes:extension_a,extension_b,...
379+
380+
The `$_FILES` item under validation must have a MIME type corresponding to one of the listed extensions.
381+
375382
<a id="rule-default"></a>
376383
#### default/defaults
377384

@@ -468,18 +475,51 @@ The field under this rule must have a size greater or equal than the given numbe
468475

469476
For string data, value corresponds to the number of characters. For numeric data, value corresponds to a given integer value. For an array, size corresponds to the count of the array.
470477

478+
You can also validate uploaded file using this rule to validate minimum size of uploaded file.
479+
For example:
480+
481+
```php
482+
$validation = $validator->validate([
483+
'photo' => $_FILES['photo']
484+
], [
485+
'photo' => 'required|min:1M'
486+
]);
487+
```
488+
471489
<a id="rule-max"></a>
472490
#### max:number
473491

474492
The field under this rule must have a size lower or equal than the given number.
475493
Value size calculated in same way like `min` rule.
476494

495+
You can also validate uploaded file using this rule to validate maximum size of uploaded file.
496+
For example:
497+
498+
```php
499+
$validation = $validator->validate([
500+
'photo' => $_FILES['photo']
501+
], [
502+
'photo' => 'required|max:2M'
503+
]);
504+
```
505+
477506
<a id="rule-between"></a>
478507
#### between:min,max
479508

480509
The field under this rule must have a size between min and max params.
481510
Value size calculated in same way like `min` and `max` rule.
482511

512+
You can also validate uploaded file using this rule to validate size of uploaded file.
513+
For example:
514+
515+
```php
516+
$validation = $validator->validate([
517+
'photo' => $_FILES['photo']
518+
], [
519+
'photo' => 'required|between:1M,2M'
520+
]);
521+
```
522+
483523
<a id="rule-digits"></a>
484524
#### digits:value
485525

composer.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,11 @@
2525
"require-dev": {
2626
"phpunit/phpunit": "^6.5",
2727
"squizlabs/php_codesniffer": "^3"
28+
},
29+
"scripts": {
30+
"test": [
31+
"phpunit",
32+
"phpcs"
33+
]
2834
}
2935
}

phpcs.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<ruleset name="Rakit validation coding standard">
3+
<description>Rakit validation coding standard</description>
4+
5+
<!-- display progress -->
6+
<arg value="p"/>
7+
<!-- use colors in output -->
8+
<arg name="colors"/>
9+
10+
<!-- inherit rules from: -->
11+
<rule ref="PSR2"/>
12+
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
13+
14+
<!-- Paths to check -->
15+
<file>src</file>
16+
<file>tests</file>
17+
</ruleset>

src/Rules/After.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class After extends Rule
88
{
99

10-
use DateUtils;
10+
use Traits\DateUtilsTrait;
1111

1212
/** @var string */
1313
protected $message = "The :attribute must be a date after :time.";

src/Rules/Before.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
class Before extends Rule
88
{
9-
use DateUtils;
9+
use Traits\DateUtilsTrait;
1010

1111
/** @var string */
1212
protected $message = "The :attribute must be a date before :time.";

src/Rules/Between.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
class Between extends Rule
88
{
9+
use Traits\SizeTrait;
910

1011
/** @var string */
1112
protected $message = "The :attribute must be between :min and :max";
@@ -23,17 +24,15 @@ public function check($value): bool
2324
{
2425
$this->requireParameters($this->fillableParams);
2526

26-
$min = (int) $this->parameter('min');
27-
$max = (int) $this->parameter('max');
27+
$min = $this->getBytesSize($this->parameter('min'));
28+
$max = $this->getBytesSize($this->parameter('max'));
2829

29-
if (is_int($value) || is_float($value)) {
30-
return $value >= $min and $value <= $max;
31-
} elseif (is_string($value)) {
32-
return mb_strlen($value, 'UTF-8') >= $min and mb_strlen($value, 'UTF-8') <= $max;
33-
} elseif (is_array($value)) {
34-
return count($value) >= $min and count($value) <= $max;
35-
} else {
30+
$valueSize = $this->getValueSize($value);
31+
32+
if (!is_numeric($valueSize)) {
3633
return false;
3734
}
35+
36+
return ($valueSize >= $min && $valueSize <= $max);
3837
}
3938
}

src/Rules/Max.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
class Max extends Rule
88
{
9+
use Traits\SizeTrait;
910

1011
/** @var string */
1112
protected $message = "The :attribute maximum is :max";
@@ -23,15 +24,13 @@ public function check($value): bool
2324
{
2425
$this->requireParameters($this->fillableParams);
2526

26-
$max = (int) $this->parameter('max');
27-
if (is_int($value)) {
28-
return $value <= $max;
29-
} elseif (is_string($value)) {
30-
return mb_strlen($value, 'UTF-8') <= $max;
31-
} elseif (is_array($value)) {
32-
return count($value) <= $max;
33-
} else {
27+
$max = $this->getBytesSize($this->parameter('max'));
28+
$valueSize = $this->getValueSize($value);
29+
30+
if (!is_numeric($valueSize)) {
3431
return false;
3532
}
33+
34+
return $valueSize <= $max;
3635
}
3736
}

src/Rules/Mimes.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace Rakit\Validation\Rules;
4+
5+
use Rakit\Validation\Rule;
6+
use Rakit\Validation\MimeTypeGuesser;
7+
8+
class Mimes extends Rule
9+
{
10+
use Traits\FileTrait;
11+
12+
/** @var string */
13+
protected $message = "The :attribute file type is not allowed";
14+
15+
/** @var string|int */
16+
protected $maxSize = null;
17+
18+
/** @var string|int */
19+
protected $minSize = null;
20+
21+
/** @var array */
22+
protected $allowedTypes = [];
23+
24+
/**
25+
* Given $params and assign $this->params
26+
*
27+
* @param array $params
28+
* @return self
29+
*/
30+
public function fillParameters(array $params): Rule
31+
{
32+
$this->allowTypes($params);
33+
return $this;
34+
}
35+
36+
/**
37+
* Given $types and assign $this->params
38+
*
39+
* @param mixed $types
40+
* @return self
41+
*/
42+
public function allowTypes($types): Rule
43+
{
44+
if (is_string($types)) {
45+
$types = explode('|', $types);
46+
}
47+
48+
$this->params['allowed_types'] = $types;
49+
50+
return $this;
51+
}
52+
53+
/**
54+
* Check the $value is valid
55+
*
56+
* @param mixed $value
57+
* @return bool
58+
*/
59+
public function check($value): bool
60+
{
61+
$allowedTypes = $this->parameter('allowed_types');
62+
63+
// below is Required rule job
64+
if (!$this->isValueFromUploadedFiles($value) or $value['error'] == UPLOAD_ERR_NO_FILE) {
65+
return true;
66+
}
67+
68+
if (!$this->isUploadedFile($value)) {
69+
return false;
70+
}
71+
72+
// just make sure there is no error
73+
if ($value['error']) {
74+
return false;
75+
}
76+
77+
if (!empty($allowedTypes)) {
78+
$guesser = new MimeTypeGuesser;
79+
$ext = $guesser->getExtension($value['type']);
80+
unset($guesser);
81+
82+
if (!in_array($ext, $allowedTypes)) {
83+
return false;
84+
}
85+
}
86+
87+
return true;
88+
}
89+
}

src/Rules/Min.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
class Min extends Rule
88
{
9+
use Traits\SizeTrait;
910

1011
/** @var string */
1112
protected $message = "The :attribute minimum is :min";
@@ -23,15 +24,13 @@ public function check($value): bool
2324
{
2425
$this->requireParameters($this->fillableParams);
2526

26-
$min = (int) $this->parameter('min');
27-
if (is_int($value)) {
28-
return $value >= $min;
29-
} elseif (is_string($value)) {
30-
return mb_strlen($value, 'UTF-8') >= $min;
31-
} elseif (is_array($value)) {
32-
return count($value) >= $min;
33-
} else {
27+
$min = $this->getBytesSize($this->parameter('min'));
28+
$valueSize = $this->getValueSize($value);
29+
30+
if (!is_numeric($valueSize)) {
3431
return false;
3532
}
33+
34+
return $valueSize >= $min;
3635
}
3736
}

src/Rules/Required.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
class Required extends Rule
88
{
9-
use FileTrait;
9+
use Traits\FileTrait;
1010

1111
/** @var bool */
1212
protected $implicit = true;

0 commit comments

Comments
 (0)