Skip to content

Commit

Permalink
Expanded DayOfMonth validation to better handle proper input
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonmantank committed Jan 23, 2017
1 parent 2f824ee commit dda25ed
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
70 changes: 69 additions & 1 deletion src/Cron/DayOfMonthField.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,76 @@ public function increment(DateTime $date, $invert = false)
return $this;
}

/**
* Validates that the value is valid for the Day of the Month field
* Days of the month can contain values of 1-31, *, L, or ? by default. This can be augmented with lists via a ',',
* ranges via a '-', or with a '[0-9]W' to specify the closest weekday.
*
* @param string $value
* @return bool
*/
public function validate($value)
{
return (bool) preg_match('/^[\*,\/\-\?LW0-9A-Za-z]+$/', $value);
// Allow wildcards and a single L
if ($value === '?' || $value === '*' || $value === 'L') {
return true;
}

// If you only contain numbers and are within 1-31
if ((bool) preg_match('/^\d{1,2}$/', $value) && ($value >= 1 && $value <= 31)) {
return true;
}

// If you have a -, we will deal with each of your chunks
if ((bool) preg_match('/-/', $value)) {
// We cannot have a range within a list or vice versa
if ((bool) preg_match('/,/', $value)) {
return false;
}

$chunks = explode('-', $value);
foreach ($chunks as $chunk) {
if (!$this->validate($chunk)) {
return false;
}
}

return true;
}

// If you have a comma, we will deal with each value
if ((bool) preg_match('/,/', $value)) {
// We cannot have a range within a list or vice versa
if ((bool) preg_match('/-/', $value)) {
return false;
}

$chunks = explode(',', $value);
foreach ($chunks as $chunk) {
if (!$this->validate($chunk)) {
return false;
}
}

return true;
}

// If you contain a /, we'll deal with it
if ((bool) preg_match('/\//', $value)) {
$chunks = explode('/', $value);
foreach ($chunks as $chunk) {
if (!$this->validate($chunk)) {
return false;
}
}
return true;
}

// If you end in W, make sure that it has a numeric in front of it
if ((bool) preg_match('/^\d{1,2}W$/', $value)) {
return true;
}

return false;
}
}
13 changes: 12 additions & 1 deletion tests/Cron/DayOfMonthFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public function testValidatesField()
$f = new DayOfMonthField();
$this->assertTrue($f->validate('1'));
$this->assertTrue($f->validate('*'));
$this->assertTrue($f->validate('*/3,1,1-12'));
$this->assertTrue($f->validate('5W,L'));
$this->assertFalse($f->validate('1.'));
}
Expand Down Expand Up @@ -47,4 +46,16 @@ public function testIncrementsDate()
$f->increment($d, true);
$this->assertEquals('2011-03-14 23:59:00', $d->format('Y-m-d H:i:s'));
}

/**
* Day of the month cannot accept a 0 value, it must be between 1 and 31
* See Github issue #120
*
* @since 2017-01-22
*/
public function testDoesNotAccept0Date()
{
$f = new DayOfMonthField();
$this->assertFalse($f->validate(0));
}
}

0 comments on commit dda25ed

Please sign in to comment.