Skip to content

Commit ac31b6b

Browse files
committed
Added field MultipleChoiceField
1 parent b5e07bd commit ac31b6b

File tree

5 files changed

+134
-5
lines changed

5 files changed

+134
-5
lines changed

src/Fields/ChoiceField.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function setChoices(array $choices)
3030
$this->widget->setChoices($choices);
3131
}
3232

33-
public function isEmpty($value)
33+
protected function isEmpty($value)
3434
{
3535
return empty($value) && $value != "0";
3636
}
@@ -44,13 +44,24 @@ public function validate($value)
4444
{
4545
parent::validate($value);
4646

47-
if ($this->isEmpty($value) || !array_key_exists($value, $this->choices)) {
47+
if ($this->isEmpty($value) || !$this->validValue($value)) {
4848
$error_message = PHPFormConfig::getIMessage("INVALID_CHOICE");
49+
50+
if (is_array($value)) {
51+
$value_diff = array_diff($value, array_keys($this->choices));
52+
$value = implode(', ', $value_diff);
53+
}
54+
4955
$message = Formatter::format($error_message, array(
50-
'choice' => $value
56+
'choice' => $value,
5157
));
5258

5359
throw new ValidationError($message, 'invalid');
5460
}
5561
}
62+
63+
protected function validValue($value)
64+
{
65+
return array_key_exists($value, $this->choices);
66+
}
5667
}

src/Fields/Field.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ public function getHelpText()
167167
return $this->help_text;
168168
}
169169

170+
/**
171+
* Check emptiness of $value
172+
* @param mixed $value
173+
* @return boolean
174+
*/
175+
protected function isEmpty($value)
176+
{
177+
return empty($value);
178+
}
179+
170180
/**
171181
* Tranforms $value into a native php object type.
172182
*
@@ -188,7 +198,7 @@ public function toNative($value)
188198
*/
189199
public function validate($value)
190200
{
191-
if (empty($value) && $this->required) {
201+
if ($this->isEmpty($value) && $this->required) {
192202
throw new ValidationError($this->error_messages['required'], 'required');
193203
}
194204
}
@@ -202,7 +212,7 @@ public function validate($value)
202212
*/
203213
public function runValidators($value)
204214
{
205-
if (empty($value)) {
215+
if ($this->isEmpty($value)) {
206216
return;
207217
}
208218

src/Fields/MultipleChoiceField.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* MultipleChoiceField 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\Widgets\SelectMultiple;
12+
13+
class MultipleChoiceField extends ChoiceField
14+
{
15+
protected $widget = SelectMultiple::class;
16+
17+
public function isEmpty($value)
18+
{
19+
return empty($value);
20+
}
21+
22+
public function toNative($value)
23+
{
24+
if ($this->isEmpty($value)) {
25+
return [];
26+
}
27+
28+
if (!is_array($value)) {
29+
$error_message = PHPFormConfig::getIMessage("INVALID_LIST");
30+
throw new ValidationError($error_message, 'invalid_list');
31+
}
32+
33+
return array_map('strval', $value);
34+
}
35+
36+
protected function validValue($value)
37+
{
38+
$keys = array_keys($this->choices);
39+
40+
return count(array_intersect($value, $keys)) == count($value);
41+
}
42+
}

src/messages.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
return array(
44
"REQUIRED" => 'This field is required.',
55
"INVALID_CHOICE" => 'Select a valid choice. "{choice}" is not one of the available choices.',
6+
"INVALID_LIST" => 'Enter a list of values.',
67
"INVALID_DATE" => 'Enter a valid date.',
78
"INVALID_DATETIME" => 'Enter a valid date/time.',
89
"INVALID_NUMBER" => 'Enter a whole number.',
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
namespace PHPForm\Unit\Fields;
3+
4+
use PHPUnit\Framework\TestCase;
5+
6+
use PHPForm\Exceptions\ValidationError;
7+
use PHPForm\Fields\MultipleChoiceField;
8+
use PHPForm\Widgets\SelectMultiple;
9+
10+
class MultipleChoiceFieldTest extends TestCase
11+
{
12+
public function setUp()
13+
{
14+
$this->choices = array(
15+
"option1" => "Option 1",
16+
"option2" => "Option 2",
17+
"option3" => "Option 3"
18+
);
19+
20+
$this->field = new MultipleChoiceField(["choices" => $this->choices, "required" => true]);
21+
}
22+
23+
public function testConstruct()
24+
{
25+
$this->assertInstanceOf(SelectMultiple::class, $this->field->getWidget());
26+
}
27+
28+
public function testToNative()
29+
{
30+
$this->assertEquals([], $this->field->toNative(false));
31+
$this->assertEquals(["1", "2", "3", "4"], $this->field->toNative([1, 2, 3, 4]));
32+
}
33+
34+
/**
35+
* @expectedException PHPForm\Exceptions\ValidationError
36+
* @expectedExceptionMessage Enter a list of values.
37+
*/
38+
public function testToNativeNonArray()
39+
{
40+
$this->field->toNative("invalid value");
41+
}
42+
43+
public function testValidateChoiceExistent()
44+
{
45+
$this->assertNull($this->field->validate(["option1", "option2"]));
46+
}
47+
48+
/**
49+
* @expectedException PHPForm\Exceptions\ValidationError
50+
* @expectedExceptionMessage This field is required.
51+
*/
52+
public function testValidateEmptyArray()
53+
{
54+
$this->field->validate([]);
55+
}
56+
57+
/**
58+
* @expectedException PHPForm\Exceptions\ValidationError
59+
* @expectedExceptionMessage Select a valid choice. "option5" is not one of the available choices.
60+
*/
61+
public function testValidateChoiceUnexistent()
62+
{
63+
$this->field->validate(["option1", "option5"]);
64+
}
65+
}

0 commit comments

Comments
 (0)