Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 52ead2a

Browse files
committed
Required Validator
1 parent 76ef192 commit 52ead2a

File tree

6 files changed

+165
-15
lines changed

6 files changed

+165
-15
lines changed

src/ArrayInput.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,22 @@ public function isValid($context = null)
6363
$hasValue = $this->hasValue();
6464
$required = $this->isRequired();
6565
$hasFallback = $this->hasFallback();
66+
$values = $this->getValue();
6667

6768
if (! $hasValue && $hasFallback) {
6869
$this->setValue($this->getFallbackValue());
6970
return true;
7071
}
7172

7273
if (! $hasValue && $required) {
73-
if ($this->errorMessage === null) {
74-
$this->setErrorMessage('Value is required');
75-
}
76-
return false;
74+
$this->injectRequiredValidator();
75+
$values = [$this];
7776
}
7877

7978
if (!$this->continueIfEmpty() && !$this->allowEmpty()) {
8079
$this->injectNotEmptyValidator();
8180
}
8281
$validator = $this->getValidatorChain();
83-
$values = $this->getValue();
8482
$result = true;
8583
foreach ($values as $value) {
8684
$empty = ($value === null || $value === '' || $value === []);

src/FileInput.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,15 @@ public function isValid($context = null)
118118
$required = $this->isRequired();
119119
$allowEmpty = $this->allowEmpty();
120120
$continueIfEmpty = $this->continueIfEmpty();
121+
$validator = $this->getValidatorChain();
121122

122123
if (! $hasValue && ! $required) {
123124
return true;
124125
}
125126

126127
if (! $hasValue && $required && ! $this->hasFallback()) {
127-
if ($this->errorMessage === null) {
128-
$this->setErrorMessage('Value is required');
129-
}
130-
return false;
128+
$this->injectRequiredValidator();
129+
return $validator->isValid($this);
131130
}
132131

133132
if ($empty && ! $required && ! $continueIfEmpty) {
@@ -139,7 +138,6 @@ public function isValid($context = null)
139138
}
140139

141140
$this->injectUploadValidator();
142-
$validator = $this->getValidatorChain();
143141
//$value = $this->getValue(); // Do not run the filters yet for File uploads (see getValue())
144142

145143
if (!is_array($rawValue)) {

src/Input.php

+28-4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ class Input implements
5959
*/
6060
protected $notEmptyValidator = false;
6161

62+
/**
63+
* @var bool If required validator is in the validator chain.
64+
*/
65+
protected $requiredValidator = false;
66+
6267
/**
6368
* @var bool
6469
*/
@@ -403,10 +408,8 @@ public function isValid($context = null)
403408
}
404409

405410
if (! $hasValue && $required) {
406-
if ($this->errorMessage === null) {
407-
$this->setErrorMessage('Value is required');
408-
}
409-
return false;
411+
$this->injectRequiredValidator();
412+
$value = $this;
410413
}
411414

412415
if ($empty && ! $required && ! $continueIfEmpty) {
@@ -483,4 +486,25 @@ protected function injectNotEmptyValidator()
483486

484487
$chain->prependValidator(new NotEmpty(), true);
485488
}
489+
490+
/**
491+
* @return void
492+
*/
493+
protected function injectRequiredValidator()
494+
{
495+
$chain = $this->getValidatorChain();
496+
497+
// Check if Required validator is already in chain
498+
$validators = $chain->getValidators();
499+
foreach ($validators as $validator) {
500+
if ($validator['instance'] instanceof Validator\Required) {
501+
$this->requiredValidator = true;
502+
return;
503+
}
504+
}
505+
506+
$this->requiredValidator = true;
507+
508+
$chain->prependValidator(new Validator\Required(), true);
509+
}
486510
}

src/Validator/Required.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Zend\InputFilter\Validator;
4+
5+
use Zend\InputFilter\Input;
6+
use Zend\Validator\AbstractValidator;
7+
8+
class Required extends AbstractValidator
9+
{
10+
const INVALID = 'inputInvalid';
11+
const REQUIRED = 'inputRequired';
12+
13+
/**
14+
* @var string[]
15+
*/
16+
protected $messageTemplates = [
17+
self::INVALID => 'Invalid type given. Zend\InputFilter\Input is required',
18+
self::REQUIRED => 'Value is required',
19+
];
20+
21+
public function isValid($value)
22+
{
23+
if (!($value instanceof Input)) {
24+
$this->error(self::INVALID);
25+
return false;
26+
}
27+
28+
$input = $value;
29+
30+
if ($input->hasValue()) { // If has value then all is ok
31+
return true;
32+
}
33+
34+
if ($input->isRequired()) { // It's Required and value was not set.
35+
$this->error(self::REQUIRED);
36+
return false;
37+
}
38+
39+
return true;
40+
}
41+
}

test/InputTest.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,15 @@ public function testRequiredWithoutFallbackAndValueNotSetThenFail()
168168
$input = $this->input;
169169
$input->setRequired(true);
170170

171+
$expectedMessages = [
172+
'inputRequired' => 'Value is required',
173+
];
174+
171175
$this->assertFalse(
172176
$input->isValid(),
173177
'isValid() should be return always false when no fallback value, is required, and not data is set.'
174178
);
175-
$this->assertEquals(['Value is required'], $input->getMessages(), 'getMessages() value not match');
179+
$this->assertEquals($expectedMessages, $input->getMessages(), 'getMessages() value not match');
176180
}
177181

178182
public function testRequiredWithoutFallbackAndValueNotSetThenFailWithCustomErrorMessage()

test/Validator/RequiredTest.php

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace ZendTest\InputFilter\Validator;
4+
5+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
6+
use PHPUnit_Framework_TestCase as TestCase;
7+
use Zend\InputFilter\Input;
8+
use Zend\InputFilter\Validator\Required;
9+
10+
/**
11+
* @covers Zend\InputFilter\Validator\Required
12+
*/
13+
class RequiredTest extends TestCase
14+
{
15+
/**
16+
* @var Required
17+
*/
18+
protected $validator;
19+
20+
protected function setUp()
21+
{
22+
$this->validator = new Required();
23+
}
24+
25+
/**
26+
* @dataProvider inputProvider
27+
*/
28+
public function testValid($input, $expectedIsValid, $expectedMessages)
29+
{
30+
$this->assertEquals(
31+
$expectedIsValid,
32+
$this->validator->isValid($input),
33+
'isValid() value not match. Detail: ' . json_encode($this->validator->getMessages())
34+
);
35+
36+
$this->assertEquals(
37+
$expectedMessages,
38+
$this->validator->getMessages(),
39+
'getMessages() value not match.'
40+
);
41+
}
42+
43+
public function inputProvider()
44+
{
45+
$requiredMsg = [
46+
Required::REQUIRED => 'Value is required',
47+
];
48+
$invalidMsg = [
49+
Required::INVALID => 'Invalid type given. Zend\InputFilter\Input is required',
50+
];
51+
52+
// @codingStandardsIgnoreStart
53+
return [
54+
// Description => [$input, isValid, getMessages]
55+
'Invalid type' => [new \stdClass() , false, $invalidMsg],
56+
'Required: T. Value: Set' => [$this->createInputMock(true, true) , true , []],
57+
'Required: T. Value: Not set' => [$this->createInputMock(true, false) , false, $requiredMsg],
58+
'Required: F. Value: set' => [$this->createInputMock(false, true) , true , []],
59+
'Required: F. Value: Not set' => [$this->createInputMock(false, false), true , []],
60+
];
61+
// @codingStandardsIgnoreEnd
62+
}
63+
64+
/**
65+
* @param bool $required
66+
* @param bool $hasValue
67+
*
68+
* @return Input|MockObject
69+
*/
70+
protected function createInputMock($required, $hasValue)
71+
{
72+
/** @var Input|MockObject $input */
73+
$input = $this->getMock(Input::class);
74+
75+
$input->method('isRequired')
76+
->willReturn($required)
77+
;
78+
79+
$input->method('hasValue')
80+
->willReturn($hasValue)
81+
;
82+
83+
return $input;
84+
}
85+
}

0 commit comments

Comments
 (0)