8000 [11.x] Add Customizable Date Validation Rule with Flexible Date Constraints by michaelnabil230 · Pull Request #53465 · laravel/framework · GitHub
[go: up one dir, main page]

Skip to content

[11.x] Add Customizable Date Validation Rule with Flexible Date Constraints #53465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
formatting
  • Loading branch information
taylorotwell committed Jan 23, 2025
commit 14a7adb8d3a4c9d29e66b467ac8b6e487552fb5e
21 changes: 10 additions & 11 deletions src/Illuminate/Validation/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ public static function prohibitedIf($callback)
return new ProhibitedIf($callback);
}

/**
* Get a date rule builder instance.
*
* @return \Illuminate\Validation\Rules\Date
*/
public static function date()
{
return new Date;
}

/**
* Get an enum rule builder instance.
*
Expand Down Expand Up @@ -201,17 +211,6 @@ public static function imageFile()
return new ImageFile;
}

/**
* Get a date rule builder instance.
*
* @param string $format
* @return \Illuminate\Validation\Rules\Date
*/
public static function date($format = 'Y-m-d')
{
return new Date($format);
}

/**
* Get a dimensions rule builder instance.
*
Expand Down
128 changes: 33 additions & 95 deletions src/Illuminate/Validation/Rules/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

namespace Illuminate\Validation\Rules;

use DateTime;
use DateTimeInterface;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\Macroable;
use Stringable;
Expand All @@ -15,155 +14,101 @@ class Date implements Stringable

/**
* The constraints for the date rule.
*
* @var array
*/
protected $constraints = ['date'];
protected array $constraints = ['date'];

/**
* The format for the date.
*
* @var string
* Ensure the date has the given format.
*/
protected $format;

/**
* Create a new date rule instance.
*
* @param string $format
* @return void
*/
public function __construct($format = 'Y-m-d')
public 8000 function format(string $format): static
{
$this->format = $format;
return $this->addRule('date_format:'.$format);
}

/**
* Specify the date format to validate against.
*
* @param ?string $format
* @return $this
* Ensure the date is before today.
*/
public function format($format = null)
public function beforeToday(): static
{
return $this->addRule('date_format:'.($format ?? $this->format));
return $this->before('today');
}

/**
* Ensure the date is after today.
*
* @return $this
*/
public function afterToday()
public function afterToday(): static
{
return $this->after('today');
}

/**
* Ensure the date is before today.
*
* @return $this
* Ensure the date is before or equal to today.
*/
public function beforeToday()
public function todayOrBefore(): static
{
return $this->before('today');
return $this->beforeOrEqual('today');
}

/**
* Ensure the date is after or equal to today.
*
* @return $this
*/
public function afterOrEqualToday()
public function todayOrAfter(): static
{
return $this->afterOrEqual('today');
}

/**
* Ensure the date is before or equal to today.
*
* @return $this
* Ensure the date is before the given date or date field.
*/
public function beforeOrEqualToday()
public function before(DateTimeInterface|string $date): static
{
return $this->beforeOrEqual('today');
return $this->addRule('before:'.$this->formatDate($date));
}

/**
* Ensure the date is after the specified date.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $date
* @return $this
* Ensure the date is after the given date or date field.
*/
public function after($date)
public function after(DateTimeInterface|string $date): static
{
return $this->addRule('after:'.$this->formatDate($date));
}

/**
* Ensure the date is before the specified date.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $date
* @return $this
* Ensure the date is on or before the specified date or date field.
*/
public function before($date)
public function beforeOrEqual(DateTimeInterface|string $date): static
{
return $this->addRule('before:'.$this->formatDate($date));
return $this->addRule('before_or_equal:'.$this->formatDate($date));
}

/**
* Ensure the date is on or after the specified date.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $date
* @return $this
* Ensure the date is on or after the given date or date field.
*/
public function afterOrEqual($date)
public function afterOrEqual(DateTimeInterface|string $date): static
{
return $this->addRule('after_or_equal:'.$this->formatDate($date));
}

/**
* Ensure the date is on or before the specified date.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $date
* @return $this
*/
public function beforeOrEqual($date)
{
return $this->addRule('before_or_equal:'.$this->formatDate($date));
}

/**
* Ensure the date is between two dates.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $from
* @param \Illuminate\Support\Carbon|\DateTime|string $to
* @return $this
* Ensure the date is between two dates or date fields.
*/
public function between($from, $to)
public function between(DateTimeInterface|string $from, DateTimeInterface|string $to): static
{
return $this->after($from)->before($to);
}

/**
* Ensure the date is between or equal to two dates.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $from
* @param \Illuminate\Support\Carbon|\DateTime|string $to
* @return $this
* Ensure the date is between or equal to two dates or date fields.
*/
public function betweenOrEqual($from, $to)
public function betweenOrEqual(DateTimeInterface|string $from, DateTimeInterface|string $to): static
{
return $this->afterOrEqual($from)->beforeOrEqual($to);
}

/**
* Add custom rules to the validation rules array.
*
* @param string|array $rules
* @return $this
*/
public function addRule($rules)
protected function addRule(array|string $rules): static
{
$this->constraints = array_merge($this->constraints, Arr::wrap($rules));

Expand All @@ -172,25 +117,18 @@ public function addRule($rules)

/**
* Format the date for the validation rule.
*
* @param \Illuminate\Support\Carbon|\DateTime|string $date
* @return string
*/
protected function formatDate($date)
protected function formatDate(DateTimeInterface|string $date): string
{
if ($date instanceof Carbon || $date instanceof DateTime) {
return $date->format($this->format);
}

return $date;
return $date instanceof DateTimeInterface
? $date->format('Y-m-d')
: $date;
}

/**
* Convert the rule to a validation string.
*
* @return string
*/
public function __toString()
public function __toString(): string
{
return implode('|', $this->constraints);
}
Expand Down
9 changes: 6 additions & 3 deletions tests/Validation/ValidationDateRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ public function testDefaultDateRule()

public function testDateFormatRule()
{
$rule = Rule::date()->format();
$this->assertEquals('date|date_format:Y-m-d', (string) $rule);

$rule = Rule::date()->format('d/m/Y');
$this->assertEquals('date|date_format:d/m/Y', (string) $rule);
}
Expand All @@ -34,12 +31,18 @@ public function testAfterTodayRule()
{
$rule = Rule::date()->afterToday();
$this->assertEquals('date|after:today', (string) $rule);

$rule = Rule::date()->todayOrAfter();
$this->assertEquals('date|after_or_equal:today', (string) $rule);
}

public function testBeforeTodayRule()
{
$rule = Rule::date()->beforeToday();
$this->assertEquals('date|before:today', (string) $rule);

$rule = Rule::date()->todayOrBefore();
$this->assertEquals('date|before_or_equal:today', (string) $rule);
}

public function testAfterSpecificDateRule()
Expand Down
0