From 7a5cdcf8a3f314e964bee3f8bdbb1e81ff7a51ef Mon Sep 17 00:00:00 2001 From: Alphametric Date: Mon, 8 Apr 2019 09:45:44 +0100 Subject: [PATCH] Added DateTimeBefore, DateTimeAfter, DateTimeBetween, Equals & FileExists --- README.md | 5 ++ src/DateTimeAfter.php | 92 +++++++++++++++++++++++++ src/DateTimeBefore.php | 92 +++++++++++++++++++++++++ src/DateTimeBetween.php | 108 ++++++++++++++++++++++++++++++ src/Decimal.php | 6 +- src/Equals.php | 44 ++++++++++++ src/FileExists.php | 50 ++++++++++++++ tests/CountryCodeTest.php | 4 +- tests/DateTimeAfterTest.php | 26 +++++++ tests/DateTimeBeforeTest.php | 26 +++++++ tests/DateTimeBetweenTest.php | 29 ++++++++ tests/DecimalTest.php | 4 +- tests/DisposableEmailTest.php | 2 +- tests/DoesNotExistTest.php | 2 +- tests/EncodedImageTest.php | 2 +- tests/EqualsTest.php | 27 ++++++++ tests/FileExistsTest.php | 46 +++++++++++++ tests/LanguageCodeTest.php | 4 +- tests/LocationCoordinatesTest.php | 2 +- tests/MonetaryFigureTest.php | 4 +- tests/RecordOwnerTest.php | 2 +- tests/StrongPasswordTest.php | 2 +- tests/TelephoneNumberTest.php | 2 +- 23 files changed, 563 insertions(+), 18 deletions(-) create mode 100644 src/DateTimeAfter.php create mode 100644 src/DateTimeBefore.php create mode 100644 src/DateTimeBetween.php create mode 100644 src/Equals.php create mode 100644 src/FileExists.php create mode 100644 tests/DateTimeAfterTest.php create mode 100644 tests/DateTimeBeforeTest.php create mode 100644 tests/DateTimeBetweenTest.php create mode 100644 tests/EqualsTest.php create mode 100644 tests/FileExistsTest.php diff --git a/README.md b/README.md index 91c6d12..843f8c6 100755 --- a/README.md +++ b/README.md @@ -41,6 +41,11 @@ The following validation rules are currently available: | Decimal | validation.decimal | Requires that the given value is a decimal with an appropriate format - see class for details | | EncodedImage | validation.encoded_image | Requires that the given value is a base64-encoded image of a given mime type - see class for details | | LocationCoordinates | validation.location_coordinates | Requires that the given value is a comma-separated set of latitude and longitude coordinates | +| DateTimeBefore | validation.datetime_before | Requires that the given value is before a given date - see class for details | +| DateTimeAfter | validation.datetime_after | Requires that the given value is after a given date - see class for details | +| DateTimeBetween | validation.datetime_between | Requires that the given value is between two dates - see class for details | +| FileExists | validation.file_exists | Requires that the given value is a path to an existing file - see class for details | +| Equals | validation.equals | Requires that the given value is equal to another given value | The package will receive new rules over time, however since these updates will not be breaking changes, they will not receive major version numbers unless Laravel changes in such a way that the package requires a re-write. diff --git a/src/DateTimeAfter.php b/src/DateTimeAfter.php new file mode 100644 index 0000000..ec098d5 --- /dev/null +++ b/src/DateTimeAfter.php @@ -0,0 +1,92 @@ +minimum = func_get_args()[0]; + $this->date_format = func_get_args()[1] ?? 'Y-m-d H:i:s'; + $this->time_zone = func_get_args()[2] ?? 'UTC'; + } + + + + /** + * Determine if the validation rule passes. + * + * The rule has three parameters: + * 1. The minimum date / time permitted. + * 2. The PHP date format, defaults to 'Y-m-d H:i:s'. + * 3. The PHP time zone, defaults to 'UTC'. + * + * @param string $attribute. + * @param mixed $value. + * @return bool. + * + **/ + public function passes($attribute, $value) + { + $boundary = Carbon::createFromFormat($this->date_format, $this->minimum, $this->time_zone); + + return Carbon::createFromFormat($this->date_format, $value, $this->time_zone)->greaterThan($boundary); + } + + + + /** + * Get the validation error message. + * + * @param none. + * @return string. + * + **/ + public function message() + { + return Helper::getLocalizedErrorMessage( + 'datetime_after', + 'The :attribute must be a date / time after ' . + Carbon::createFromFormat($this->date_format, $this->minimum, $this->time_zone) + ->format('jS F Y @ g:i:s A') + ); + } + +} \ No newline at end of file diff --git a/src/DateTimeBefore.php b/src/DateTimeBefore.php new file mode 100644 index 0000000..f12c319 --- /dev/null +++ b/src/DateTimeBefore.php @@ -0,0 +1,92 @@ +maximum = func_get_args()[0]; + $this->date_format = func_get_args()[1] ?? 'Y-m-d H:i:s'; + $this->time_zone = func_get_args()[2] ?? 'UTC'; + } + + + + /** + * Determine if the validation rule passes. + * + * The rule has three parameters: + * 1. The maximum date / time permitted. + * 2. The PHP date format, defaults to 'Y-m-d H:i:s'. + * 3. The PHP time zone, defaults to 'UTC'. + * + * @param string $attribute. + * @param mixed $value. + * @return bool. + * + **/ + public function passes($attribute, $value) + { + $boundary = Carbon::createFromFormat($this->date_format, $this->maximum, $this->time_zone); + + return Carbon::createFromFormat($this->date_format, $value, $this->time_zone)->lessThan($boundary); + } + + + + /** + * Get the validation error message. + * + * @param none. + * @return string. + * + **/ + public function message() + { + return Helper::getLocalizedErrorMessage( + 'datetime_before', + 'The :attribute must be a date / time before ' . + Carbon::createFromFormat($this->date_format, $this->maximum, $this->time_zone) + ->format('jS F Y @ g:i:s A') + ); + } + +} \ No newline at end of file diff --git a/src/DateTimeBetween.php b/src/DateTimeBetween.php new file mode 100644 index 0000000..e1a8416 --- /dev/null +++ b/src/DateTimeBetween.php @@ -0,0 +1,108 @@ +minimum = func_get_args()[0]; + $this->maximum = func_get_args()[1]; + $this->date_format = func_get_args()[2] ?? 'Y-m-d H:i:s'; + $this->time_zone = func_get_args()[3] ?? 'UTC'; + } + + + + /** + * Determine if the validation rule passes. + * + * The rule has four parameters: + * 1. The minimum date / time permitted. + * 2. The maximum date / time permitted. + * 3. The PHP date format, defaults to 'Y-m-d H:i:s'. + * 4. The PHP time zone, defaults to 'UTC'. + * + * @param string $attribute. + * @param mixed $value. + * @return bool. + * + **/ + public function passes($attribute, $value) + { + $boundary_start = Carbon::createFromFormat($this->date_format, $this->minimum, $this->time_zone); + $boundary_finish = Carbon::createFromFormat($this->date_format, $this->maximum, $this->time_zone); + + $date_time = Carbon::createFromFormat($this->date_format, $value, $this->time_zone); + + return $date_time->greaterThan($boundary_start) && $date_time->lessThan($boundary_finish); + } + + + + /** + * Get the validation error message. + * + * @param none. + * @return string. + * + **/ + public function message() + { + return Helper::getLocalizedErrorMessage( + 'datetime_between', + 'The :attribute must be a date / time after ' . + Carbon::createFromFormat($this->date_format, $this->minimum, $this->time_zone) + ->format('jS F Y @ g:i:s A') . + ' and before ' . + Carbon::createFromFormat($this->date_format, $this->maximum, $this->time_zone) + ->format('jS F Y @ g:i:s A') + ); + } + +} \ No newline at end of file diff --git a/src/Decimal.php b/src/Decimal.php index 38886e7..9e33255 100644 --- a/src/Decimal.php +++ b/src/Decimal.php @@ -25,9 +25,9 @@ public function example() /** * Determine if the validation rule passes. * - * The decimal requires two parameters: - * 2. The maximum number of digits before the decimal point. - * 3. The maximum number of digits after the decimal point. + * The rule has two parameters: + * 1. The maximum number of digits before the decimal point. + * 2. The maximum number of digits after the decimal point. * * @param string $attribute. * @param mixed $value. diff --git a/src/Equals.php b/src/Equals.php new file mode 100644 index 0000000..267cf28 --- /dev/null +++ b/src/Equals.php @@ -0,0 +1,44 @@ +parameters[0] === $value; + } + + + + /** + * Get the validation error message. + * + * @param none. + * @return string. + * + **/ + public function message() + { + return Helper::getLocalizedErrorMessage( + 'equals', + 'The :attribute must be set to "' . $this->parameters[0] . '"' + ); + } + +} \ No newline at end of file diff --git a/src/FileExists.php b/src/FileExists.php new file mode 100644 index 0000000..a9bf888 --- /dev/null +++ b/src/FileExists.php @@ -0,0 +1,50 @@ +parameters[1] ?? '', '/'); + $file = ltrim($value, '/'); + + return Storage::disk($this->parameters[0])->exists("$path/$file"); + } + + + + /** + * Get the validation error message. + * + * @param none. + * @return string. + * + **/ + public function message() + { + return Helper::getLocalizedErrorMessage( + 'file_exists', + 'The file specified for :attribute does not exist' + ); + } + +} \ No newline at end of file diff --git a/tests/CountryCodeTest.php b/tests/CountryCodeTest.php index f62e314..b021a71 100644 --- a/tests/CountryCodeTest.php +++ b/tests/CountryCodeTest.php @@ -12,7 +12,7 @@ class CountryCodeTest extends Orchestra { /** @test */ - public function a_two_letter_country_code_can_be_validated() + public function the_two_letter_country_code_rule_can_be_validated() { // Define the validation rule $rule = ['code' => [new CountryCode(2)]]; @@ -26,7 +26,7 @@ public function a_two_letter_country_code_can_be_validated() /** @test */ - public function a_three_letter_country_code_can_be_validated() + public function the_three_letter_country_code_rule_can_be_validated() { // Define the validation rule $rule = ['code' => [new CountryCode(3)]]; diff --git a/tests/DateTimeAfterTest.php b/tests/DateTimeAfterTest.php new file mode 100644 index 0000000..e63fd5d --- /dev/null +++ b/tests/DateTimeAfterTest.php @@ -0,0 +1,26 @@ + [new DateTimeAfter(now()->format('Y-m-d H:i:s'))]]; + + // Execute the tests + $this->assertFalse(validator(['datetime' => now()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertFalse(validator(['datetime' => now()->subMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertTrue(validator(['datetime' => now()->addMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + } + +} \ No newline at end of file diff --git a/tests/DateTimeBeforeTest.php b/tests/DateTimeBeforeTest.php new file mode 100644 index 0000000..b337c1d --- /dev/null +++ b/tests/DateTimeBeforeTest.php @@ -0,0 +1,26 @@ + [new DateTimeBefore(now()->format('Y-m-d H:i:s'))]]; + + // Execute the tests + $this->assertFalse(validator(['datetime' => now()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertTrue(validator(['datetime' => now()->subMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertFalse(validator(['datetime' => now()->addMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + } + +} \ No newline at end of file diff --git a/tests/DateTimeBetweenTest.php b/tests/DateTimeBetweenTest.php new file mode 100644 index 0000000..ffa9e44 --- /dev/null +++ b/tests/DateTimeBetweenTest.php @@ -0,0 +1,29 @@ + [new DateTimeBetween(now()->format('Y-m-d H:i:s'), now()->addWeek()->format('Y-m-d H:i:s'))]]; + + // Execute the tests + $this->assertFalse(validator(['datetime' => now()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertFalse(validator(['datetime' => now()->subMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertTrue(validator(['datetime' => now()->addMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertTrue(validator(['datetime' => now()->addDay()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertTrue(validator(['datetime' => now()->addDay()->format('Y-m-d H:i:s')], $rule)->passes()); + $this->assertFalse(validator(['datetime' => now()->addWeek()->addMinute()->format('Y-m-d H:i:s')], $rule)->passes()); + } + +} \ No newline at end of file diff --git a/tests/DecimalTest.php b/tests/DecimalTest.php index 144e103..d80d3a3 100644 --- a/tests/DecimalTest.php +++ b/tests/DecimalTest.php @@ -12,7 +12,7 @@ class DecimalTest extends Orchestra { /** @test */ - public function a_decimal_can_be_validated() + public function the_decimal_rule_can_be_validated() { // Define the validation rule $rule = ['figure' => [new Decimal(4, 2)]]; @@ -32,7 +32,7 @@ public function a_decimal_can_be_validated() /** @test */ - public function a_decimal_example_is_valid() + public function the_decimal_rule_example_is_valid() { // Define the validation rule $rule = ['figure' => [$class = new Decimal(4, 2)]]; diff --git a/tests/DisposableEmailTest.php b/tests/DisposableEmailTest.php index 0ff7dca..04d133a 100644 --- a/tests/DisposableEmailTest.php +++ b/tests/DisposableEmailTest.php @@ -12,7 +12,7 @@ class DisposableEmailTest extends Orchestra { /** @test */ - public function a_disposable_email_can_be_validated() + public function the_disposable_email_rule_can_be_validated() { // Define the validation rule $rule = ['email' => ['bail', 'email', new DisposableEmail()]]; diff --git a/tests/DoesNotExistTest.php b/tests/DoesNotExistTest.php index aa10173..54c79d8 100644 --- a/tests/DoesNotExistTest.php +++ b/tests/DoesNotExistTest.php @@ -68,7 +68,7 @@ protected function seedDatabase() /** @test */ - public function a_does_not_exist_can_be_validated() + public function the_does_not_exist_rule_can_be_validated() { // Generate the fake data $this->seedDatabase(); diff --git a/tests/EncodedImageTest.php b/tests/EncodedImageTest.php index efc925e..e32e49a 100644 --- a/tests/EncodedImageTest.php +++ b/tests/EncodedImageTest.php @@ -44,7 +44,7 @@ protected function invalidImage($mime = "") /** @test */ - public function a_encoded_jpeg_image_can_be_validated() + public function the_encoded_jpeg_image_rule_can_be_validated() { // Define the validation rule $png_rule = ['image' => [new EncodedImage('png')]]; diff --git a/tests/EqualsTest.php b/tests/EqualsTest.php new file mode 100644 index 0000000..7958e8e --- /dev/null +++ b/tests/EqualsTest.php @@ -0,0 +1,27 @@ + [new Equals('2')]]; + + // Execute the tests + $this->assertFalse(validator(['value' => '0'], $rule)->passes()); + $this->assertFalse(validator(['value' => '1'], $rule)->passes()); + $this->assertTrue(validator(['value' => '2'], $rule)->passes()); + $this->assertFalse(validator(['value' => '3'], $rule)->passes()); + } + +} \ No newline at end of file diff --git a/tests/FileExistsTest.php b/tests/FileExistsTest.php new file mode 100644 index 0000000..91278cd --- /dev/null +++ b/tests/FileExistsTest.php @@ -0,0 +1,46 @@ +set('filesystems.disks.local', [ + 'driver' => 'local', + 'root' => realpath(__DIR__ . '/..') . '/support/assets', + ]); + } + + + + /** @test */ + public function the_file_exists_rule_can_be_validated() + { + // Define the validation rule + $rule = ['file' => [new FileExists('local', '/')]]; + + // Execute the assertions + $this->assertTrue(validator(['file' => 'image.png'], $rule)->passes()); + $this->assertTrue(validator(['file' => '/image.png'], $rule)->passes()); + $this->assertFalse(validator(['file' => '/fake.png'], $rule)->passes()); + $this->assertFalse(validator(['file' => 'fake.png'], $rule)->passes()); + } + +} \ No newline at end of file diff --git a/tests/LanguageCodeTest.php b/tests/LanguageCodeTest.php index 98b2f38..589e94f 100644 --- a/tests/LanguageCodeTest.php +++ b/tests/LanguageCodeTest.php @@ -12,7 +12,7 @@ class LanguageCodeTest extends Orchestra { /** @test */ - public function a_two_letter_language_code_can_be_validated() + public function the_two_letter_language_code_rule_can_be_validated() { // Define the validation rule $rule = ['code' => [new LanguageCode(2)]]; @@ -26,7 +26,7 @@ public function a_two_letter_language_code_can_be_validated() /** @test */ - public function a_three_letter_language_code_can_be_validated() + public function the_three_letter_language_code_rule_can_be_validated() { // Define the validation rule $rule = ['code' => [new LanguageCode(3)]]; diff --git a/tests/LocationCoordinatesTest.php b/tests/LocationCoordinatesTest.php index 1458ef1..c541a0c 100644 --- a/tests/LocationCoordinatesTest.php +++ b/tests/LocationCoordinatesTest.php @@ -12,7 +12,7 @@ class LocationCoordinatesTest extends Orchestra { /** @test */ - public function a_set_of_location_coordinates_can_be_validated() + public function the_location_coordinates_rule_can_be_validated() { // Define the validation rule $rule = ['location' => [new LocationCoordinates]]; diff --git a/tests/MonetaryFigureTest.php b/tests/MonetaryFigureTest.php index 80b43ea..0b5ff50 100644 --- a/tests/MonetaryFigureTest.php +++ b/tests/MonetaryFigureTest.php @@ -12,7 +12,7 @@ class MonetaryFigureTest extends Orchestra { /** @test */ - public function a_monetary_figure_can_be_validated() + public function the_monetary_figure_rule_can_be_validated() { // Define the validation rule $rule = ['deposit' => [new MonetaryFigure('$', 4, 4)]]; @@ -37,7 +37,7 @@ public function a_monetary_figure_can_be_validated() /** @test */ - public function a_monetary_figure_example_is_valid() + public function the_monetary_figure_rule_example_is_valid() { // Define the validation rule $rule = ['deposit' => [$class = new MonetaryFigure('$', 4, 2)]]; diff --git a/tests/RecordOwnerTest.php b/tests/RecordOwnerTest.php index 8b6d2de..27b3466 100644 --- a/tests/RecordOwnerTest.php +++ b/tests/RecordOwnerTest.php @@ -98,7 +98,7 @@ protected function seedDatabase() /** @test */ - public function a_record_owner_can_be_validated() + public function the_record_owner_rule_can_be_validated() { // Generate the fake data $this->seedDatabase(); diff --git a/tests/StrongPasswordTest.php b/tests/StrongPasswordTest.php index 54e9c1e..91931d0 100644 --- a/tests/StrongPasswordTest.php +++ b/tests/StrongPasswordTest.php @@ -12,7 +12,7 @@ class StrongPasswordTest extends Orchestra { /** @test */ - public function a_strong_password_can_be_validated() + public function the_strong_password_rule_can_be_validated() { // Define the validation rule $rule = ['password' => [new StrongPassword]]; diff --git a/tests/TelephoneNumberTest.php b/tests/TelephoneNumberTest.php index 0ee488b..950ad27 100644 --- a/tests/TelephoneNumberTest.php +++ b/tests/TelephoneNumberTest.php @@ -12,7 +12,7 @@ class TelephoneNumberTest extends Orchestra { /** @test */ - public function a_telephone_number_can_be_validated() + public function the_telephone_number_rule_can_be_validated() { // Define the validation rule $rule = ['phone' => [new TelephoneNumber]];