Skip to content

Commit ba4a90e

Browse files
committed
Added field FileField
1 parent 02fbb1f commit ba4a90e

File tree

7 files changed

+255
-8
lines changed

7 files changed

+255
-8
lines changed

src/Fields/FileField.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
/**
3+
* FileField Class
4+
*/
5+
namespace PHPForm\Fields;
6+
7+
use Fleshgrinder\Core\Formatter;
8+
9+
use PHPForm\Exceptions\ValidationError;
10+
use PHPForm\PHPFormConfig;
11+
use PHPForm\Validators\FileTypeValidator;
12+
use PHPForm\Widgets\FileInput;
13+
14+
class FileField extends Field
15+
{
16+
protected $widget = FileInput::class;
17+
18+
/**
19+
* Constructor with extra args min_length and max_length
20+
*
21+
* @param array
22+
*/
23+
public function __construct(array $args = array())
24+
{
25+
$this->max_size = array_key_exists('max_size', $args) ? $args['max_size'] : null;
26+
$this->valid_filetypes = array_key_exists('valid_filetypes', $args) ? $args['valid_filetypes'] : null;
27+
28+
parent::__construct($args);
29+
30+
if (!is_null($this->valid_filetypes)) {
31+
$this->validators[] = new FileTypeValidator($this->valid_filetypes);
32+
}
33+
}
34+
35+
public function validate($value)
36+
{
37+
if (0 == $value->size && $this->required) {
38+
throw new ValidationError($this->error_messages['required'], 'required');
39+
}
40+
41+
if (0 == $value->size) {
42+
$errormsg = PHPFormConfig::getIMessage("EMPTY_FILE");
43+
throw new ValidationError($errormsg, 'empty_file');
44+
}
45+
46+
if (!is_null($this->max_size) && $value->size >= $this->max_size) {
47+
$errormsg = PHPFormConfig::getIMessage("INVALID_FILE_MAX_SIZE");
48+
49+
$message = Formatter::format($errormsg, array(
50+
"limit" => $this->max_size,
51+
"value" => $value->size
52+
));
53+
54+
throw new ValidationError($message, 'max_size');
55+
}
56+
}
57+
58+
public function toNative($value)
59+
{
60+
if (!is_array($value)) {
61+
throw new ValidationError(PHPFormConfig::getIMessage("INVALID_FILE"), 'invalid');
62+
}
63+
64+
return (object) $value;
65+
}
66+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Validator to check if $value is an valid email
4+
*/
5+
namespace PHPForm\Validators;
6+
7+
use Fleshgrinder\Core\Formatter;
8+
9+
use PHPForm\Exceptions\ValidationError;
10+
use PHPForm\PHPFormConfig;
11+
use PHPForm\Validators\Validator;
12+
13+
class FileTypeValidator extends Validator
14+
{
15+
protected $code = "invalid_file_type";
16+
17+
public function __construct(array $valid_filetypes, $message = null)
18+
{
19+
$this->valid_filetypes = $valid_filetypes;
20+
21+
if (is_null($message)) {
22+
$message = PHPFormConfig::getIMessage("INVALID_FILE_TYPE");
23+
}
24+
25+
parent::__construct($message);
26+
}
27+
28+
public function __invoke($value)
29+
{
30+
if (!is_null($this->valid_filetypes) && !in_array($value->type, $this->valid_filetypes)) {
31+
$message = Formatter::format($this->message, array(
32+
"valid_types" => implode(", ", $this->valid_filetypes),
33+
"type" => $value->type
34+
));
35+
36+
throw new ValidationError($message, 'invalid_file_type');
37+
}
38+
}
39+
}

src/messages.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
"INVALID_NUMBER" => 'Enter a whole number.',
99
"INVALID_EMAIL" => 'Enter a valid email address.',
1010
"INVALID_URL" => 'Enter a valid URL.',
11+
"INVALID_FILE" => 'Invalid file submitted.',
12+
"EMPTY_FILE" => 'The submitted file is empty.',
13+
"INVALID_FILE_MAX_SIZE" => 'Ensure the file has at most {limit} bytes (it has {value} bytes).',
14+
"INVALID_FILE_TYPE" => 'Ensure the file is one of "{valid_types}" types (it has {type}).',
1115
"INVALID_MAX_LENGTH" => 'Ensure this value has at most {limit} character (it has {value}).',
1216
"INVALID_MAX_VALUE" => 'Ensure this value is less than or equal to {limit}.',
1317
"INVALID_MIN_LENGTH" => 'Ensure this value has at least {limit} character (it has {value}).',
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
namespace PHPForm\Unit\Fields;
3+
4+
use PHPUnit\Framework\TestCase;
5+
6+
use PHPForm\Exceptions\ValidationError;
7+
use PHPForm\Fields\FileField;
8+
use PHPForm\Widgets\FileInput;
9+
10+
class FileFieldTest extends TestCase
11+
{
12+
public function setUp()
13+
{
14+
$this->field = new FileField(["max_size" => 20]);
15+
}
16+
17+
public function testConstruct()
18+
{
19+
$this->assertInstanceOf(FileInput::class, $this->field->getWidget());
20+
$this->assertAttributeEquals(20, "max_size", $this->field);
21+
}
22+
23+
/**
24+
* @expectedException PHPForm\Exceptions\ValidationError
25+
* @expectedExceptionMessage The submitted file is empty.
26+
*/
27+
public function testValidateEmpty()
28+
{
29+
$data = array('size' => 0);
30+
$this->field->validate((object) $data);
31+
}
32+
33+
/**
34+
* @expectedException PHPForm\Exceptions\ValidationError
35+
* @expectedExceptionMessage This field is required.
36+
*/
37+
public function testValidateEmptyRequired()
38+
{
39+
$data = array('size' => 0);
40+
41+
$field = new FileField(["required" => true]);
42+
$field->validate((object) $data);
43+
}
44+
45+
46+
/**
47+
* @expectedException PHPForm\Exceptions\ValidationError
48+
* @expectedExceptionMessage Ensure the file has at most 20 bytes (it has 100 bytes).
49+
*/
50+
public function testValidateMaxSize()
51+
{
52+
$data = array('size' => 100);
53+
54+
$this->field->validate((object) $data);
55+
}
56+
57+
public function testToNative()
58+
{
59+
$data = array(
60+
'name' => 'mine_small.jpg',
61+
'type' => 'image/jpeg',
62+
'tmp_name' => '/data/tmp/php/uploads/phpscF9Uz',
63+
'size' => 13481,
64+
);
65+
66+
$result = $this->field->toNative($data);
67+
68+
$this->assertEquals($data['name'], $result->name);
69+
$this->assertEquals($data['type'], $result->type);
70+
$this->assertEquals($data['tmp_name'], $result->tmp_name);
71+
$this->assertEquals($data['size'], $result->size);
72+
}
73+
74+
/**
75+
* @expectedException PHPForm\Exceptions\ValidationError
76+
* @expectedExceptionMessage Invalid file submitted.
77+
*/
78+
public function testToNativeInvalidValue()
79+
{
80+
$this->field->toNative("string");
81+
}
82+
83+
/**
84+
* @expectedException PHPForm\Exceptions\ValidationError
85+
*/
86+
public function testFileTypeValidatorCalled()
87+
{
88+
$data = array('size' => 10, 'type' => 'image/jpeg',);
89+
90+
$field = new FileField(["valid_filetypes" => ['image/png']]);
91+
$field->clean($data);
92+
}
93+
}

tests/unit/PHPFormConfigTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,29 @@ public function testGetInstance()
1414

1515
public function testGetIMessage()
1616
{
17-
$this->assertEquals(PHPFormConfig::getIMessage("Invalid"), "Invalid");
17+
$this->assertEquals(PHPFormConfig::getIMessage("REQUIRED"), "This field is required.");
1818
$this->assertNull(PHPFormConfig::getIMessage("Inexistent"));
1919
}
2020

2121
public function testGetMessage()
2222
{
2323
$instance = PHPFormConfig::getInstance();
2424

25-
$this->assertEquals($instance->getMessage("Invalid"), "Invalid");
25+
$this->assertEquals($instance->getMessage("REQUIRED"), "This field is required.");
2626
$this->assertNull($instance->getMessage("Inexistent"));
2727
}
2828

2929
public function testGetITemplate()
3030
{
31-
$this->assertEquals(PHPFormConfig::getITemplate("Invalid"), "Invalid");
31+
$this->assertEquals(PHPFormConfig::getITemplate("LABEL_REQUIRED"), '<span class="required">*</span>');
3232
$this->assertNull(PHPFormConfig::getITemplate("Inexistent"));
3333
}
3434

3535
public function testGetTemplate()
3636
{
3737
$instance = PHPFormConfig::getInstance();
3838

39-
$this->assertEquals($instance->getTemplate("Invalid"), "Invalid");
39+
$this->assertEquals($instance->getTemplate("LABEL_REQUIRED"), '<span class="required">*</span>');
4040
$this->assertNull($instance->getTemplate("Inexistent"));
4141
}
4242

@@ -48,7 +48,7 @@ public function testSetMessages()
4848
"Invalid 3" => "Invalid 3",
4949
));
5050

51-
$this->assertEquals("Invalid", $instance->getMessage("Invalid"));
51+
$this->assertEquals("This field is required.", $instance->getMessage("REQUIRED"));
5252
$this->assertEquals("Invalid 2", $instance->getMessage("Invalid 2"));
5353
$this->assertEquals("Invalid 3", $instance->getMessage("Invalid 3"));
5454
}
@@ -61,7 +61,7 @@ public function testSetTemplates()
6161
"Invalid 3" => "Invalid 3",
6262
));
6363

64-
$this->assertEquals("Invalid", $instance->getTemplate("Invalid"));
64+
$this->assertEquals('<span class="required">*</span>', $instance->getTemplate("LABEL_REQUIRED"));
6565
$this->assertEquals("Invalid 2", $instance->getTemplate("Invalid 2"));
6666
$this->assertEquals("Invalid 3", $instance->getTemplate("Invalid 3"));
6767
}

tests/unit/Validators/EmailValidatorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function testValidEmail()
2121
public function testInvalidEmail()
2222
{
2323
$validator = new EmailValidator();
24-
$this->assertNull($validator("@example.com"));
24+
$validator("@example.com");
2525
}
2626

2727
/**
@@ -31,6 +31,6 @@ public function testInvalidEmail()
3131
public function testInvalidEmailWithDifferentMessage()
3232
{
3333
$validator = new EmailValidator("Invalid email.");
34-
$this->assertNull($validator("@example.com"));
34+
$validator("@example.com");
3535
}
3636
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
namespace PHPForm\Unit\Validators;
3+
4+
use PHPUnit\Framework\TestCase;
5+
6+
use PHPForm\Validators\FileTypeValidator;
7+
use PHPForm\Exceptions\ValidationError;
8+
9+
class FileTypeValidatorTest extends TestCase
10+
{
11+
12+
public function setUp()
13+
{
14+
$this->data = (object) array('type' => 'image/png');
15+
}
16+
17+
public function testValidType()
18+
{
19+
$validator = new FileTypeValidator(['image/png']);
20+
21+
$this->assertNull($validator($this->data));
22+
}
23+
24+
/**
25+
* @expectedException PHPForm\Exceptions\ValidationError
26+
* @expectedExceptionMessage Ensure the file is one of "image/jpeg" types (it has image/png).
27+
*/
28+
public function testInvalidType()
29+
{
30+
$validator = new FileTypeValidator(['image/jpeg']);
31+
32+
$validator($this->data);
33+
}
34+
35+
/**
36+
* @expectedException PHPForm\Exceptions\ValidationError
37+
* @expectedExceptionMessage Invalid type.
38+
*/
39+
public function testInvalidEmailWithDifferentMessage()
40+
{
41+
$validator = new FileTypeValidator(['image/jpeg', "Invalid type."]);
42+
43+
$validator($this->data);
44+
}
45+
}

0 commit comments

Comments
 (0)