diff --git a/src/Illuminate/Translation/lang/en/validation.php b/src/Illuminate/Translation/lang/en/validation.php index f19bd64ed6c9..2297bd679969 100644 --- a/src/Illuminate/Translation/lang/en/validation.php +++ b/src/Illuminate/Translation/lang/en/validation.php @@ -50,6 +50,7 @@ 'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.', 'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.', 'email' => 'The :attribute field must be a valid email address.', + 'even' => 'The :attribute field must be an even number.', 'ends_with' => 'The :attribute field must end with one of the following: :values.', 'enum' => 'The selected :attribute is invalid.', 'exists' => 'The selected :attribute is invalid.', @@ -117,6 +118,7 @@ 'not_in' => 'The selected :attribute is invalid.', 'not_regex' => 'The :attribute field format is invalid.', 'numeric' => 'The :attribute field must be a number.', + 'odd' => 'The :attribute field must be an odd number.', 'password' => [ 'letters' => 'The :attribute field must contain at least one letter.', 'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.', diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index 21577ce4eb87..db64da558c03 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -2477,6 +2477,30 @@ public function validateSize($attribute, $value, $parameters) return BigNumber::of($this->getSize($attribute, $value))->isEqualTo($this->trim($parameters[0])); } + /** + * Validate that a numeric attribute is even. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + public function validateEven($attribute, $value) + { + return $this->validateNumeric($attribute, $value) && BigNumber::of($this->trim($value))->isEven(); + } + + /** + * Validate that a numeric attribute is odd. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + public function validateOdd($attribute, $value) + { + return $this->validateNumeric($attribute, $value) && BigNumber::of($this->trim($value))->isOdd(); + } + /** * "Validate" optional attributes. * diff --git a/src/Illuminate/Validation/Rules/Numeric.php b/src/Illuminate/Validation/Rules/Numeric.php index 0adde2f98e3e..8cbfba3c80c1 100644 --- a/src/Illuminate/Validation/Rules/Numeric.php +++ b/src/Illuminate/Validation/Rules/Numeric.php @@ -210,6 +210,26 @@ public function exactly(int $value): Numeric return $this->integer()->addRule('size:'.$value); } + /** + * The field under validation must be an even number. + * + * @return $this + */ + public function even(): Numeric + { + return $this->addRule('even'); + } + + /** + * The field under validation must be an odd number. + * + * @return $this + */ + public function odd(): Numeric + { + return $this->addRule('odd'); + } + /** * Convert the rule to a validation string. */ diff --git a/tests/Validation/ValidationNumericRuleTest.php b/tests/Validation/ValidationNumericRuleTest.php index d7f2ca2c7b35..415ac56dd6a3 100644 --- a/tests/Validation/ValidationNumericRuleTest.php +++ b/tests/Validation/ValidationNumericRuleTest.php @@ -355,4 +355,16 @@ public function testUniquenessValidation() $rule = Rule::numeric()->integer()->digits(2)->exactly(2); $this->assertEquals('numeric|integer|digits:2|size:2', (string) $rule); } + + public function testEvenRule() + { + $rule = Rule::numeric()->even(); + $this->assertEquals('numeric|even', (string) $rule); + } + + public function testOddRule() + { + $rule = Rule::numeric()->odd(); + $this->assertEquals('numeric|odd', (string) $rule); + } } diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 167711851fab..55214ba6f0ec 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -9616,6 +9616,66 @@ public function testItTrimsSpaceFromParameters() ], $validator->messages()->keys()); } + public function testValidationPassesWithEvenNumber() + { + $v = new Validator( + $this->getIlluminateArrayTranslator(), + [ + 'number' => 2, + ], + [ + 'number' => 'even', + ] + ); + + $this->assertFalse($v->fails()); + } + + public function testValidationFailsWithEvenNumber() + { + $v = new Validator( + $this->getIlluminateArrayTranslator(), + [ + 'number' => 3, + ], + [ + 'number' => 'even', + ] + ); + + $this->assertTrue($v->fails()); + } + + public function testValidationPassWithOddNumber() + { + $v = new Validator( + $this->getIlluminateArrayTranslator(), + [ + 'number' => 3, + ], + [ + 'number' => 'odd', + ] + ); + + $this->assertFalse($v->fails()); + } + + public function testValidationFailsWithOddNumber() + { + $v = new Validator( + $this->getIlluminateArrayTranslator(), + [ + 'number' => 4, + ], + [ + 'number' => 'odd', + ] + ); + + $this->assertTrue($v->fails()); + } + #[DataProvider('outsideRangeExponents')] public function testItLimitsLengthOfScientificNotationExponent($value) {