diff --git a/src/Event.php b/src/Event.php index 0f67428..5452453 100644 --- a/src/Event.php +++ b/src/Event.php @@ -1033,62 +1033,62 @@ public function refreshLock(): void public function everyMinute(): self { - return $this->cron('* * * * *'); + return $this->cronPreservingCurrentDayOfWeek('* * * * *'); } public function everyTwoMinutes(): self { - return $this->cron('*/2 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/2 * * * *'); } public function everyThreeMinutes(): self { - return $this->cron('*/3 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/3 * * * *'); } public function everyFourMinutes(): self { - return $this->cron('*/4 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/4 * * * *'); } public function everyFiveMinutes(): self { - return $this->cron('*/5 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/5 * * * *'); } public function everyTenMinutes(): self { - return $this->cron('*/10 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/10 * * * *'); } public function everyFifteenMinutes(): self { - return $this->cron('*/15 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/15 * * * *'); } public function everyThirtyMinutes(): self { - return $this->cron('*/30 * * * *'); + return $this->cronPreservingCurrentDayOfWeek('*/30 * * * *'); } public function everyTwoHours(): self { - return $this->cron('0 */2 * * *'); + return $this->cronPreservingCurrentDayOfWeek('0 */2 * * *'); } public function everyThreeHours(): self { - return $this->cron('0 */3 * * *'); + return $this->cronPreservingCurrentDayOfWeek('0 */3 * * *'); } public function everyFourHours(): self { - return $this->cron('0 */4 * * *'); + return $this->cronPreservingCurrentDayOfWeek('0 */4 * * *'); } public function everySixHours(): self { - return $this->cron('0 */6 * * *'); + return $this->cronPreservingCurrentDayOfWeek('0 */6 * * *'); } /** @@ -1246,6 +1246,28 @@ protected function applyMask($unit) return $this->cron(\implode(' ', $cron)); } + /** + * Preserve day-of-week constraints while applying every* frequency shortcuts. + */ + protected function cronPreservingCurrentDayOfWeek(string $expression): self + { + $weekdayPosition = $this->fieldsPosition['week'] - 1; + $currentExpressionParts = \preg_split('/\s+/', $this->expression, -1, PREG_SPLIT_NO_EMPTY); + $newExpressionParts = \preg_split('/\s+/', $expression, -1, PREG_SPLIT_NO_EMPTY); + $currentExpressionParts = false === $currentExpressionParts ? [] : $currentExpressionParts; + $newExpressionParts = false === $newExpressionParts ? [] : $newExpressionParts; + + if ( + isset($currentExpressionParts[$weekdayPosition], $newExpressionParts[$weekdayPosition]) + && '*' !== $currentExpressionParts[$weekdayPosition] + && '*' === $newExpressionParts[$weekdayPosition] + ) { + $newExpressionParts[$weekdayPosition] = $currentExpressionParts[$weekdayPosition]; + } + + return $this->cron(\implode(' ', $newExpressionParts)); + } + /** * Lock the event. */ diff --git a/tests/Unit/EventTest.php b/tests/Unit/EventTest.php index 9299a9c..cd13c19 100644 --- a/tests/Unit/EventTest.php +++ b/tests/Unit/EventTest.php @@ -434,6 +434,50 @@ public function test_every_methods(string $method, string $expectedCronExpressio self::assertSame($expectedCronExpression, $event->getExpression()); } + /** @dataProvider everyMethodProvider */ + public function test_every_methods_keep_weekday_constraint(string $method, string $expectedCronExpression): void + { + // Arrange + $event = new Event($this->id, 'php -i'); + $event->mondays(); + /** @var callable $methodCall */ + $methodCall = [$event, $method]; + $methodCallClosure = \Closure::fromCallable($methodCall); + + $expressionParts = \explode(' ', $expectedCronExpression); + $dayOfWeekPosition = \count($expressionParts) - 1; + $expressionParts[$dayOfWeekPosition] = '1'; + $expectedExpression = \implode(' ', $expressionParts); + + // Act + $methodCallClosure(); + + // Assert + self::assertSame($expectedExpression, $event->getExpression()); + } + + /** @dataProvider everyMethodProvider */ + public function test_every_methods_keep_comma_separated_weekday_constraint(string $method, string $expectedCronExpression): void + { + // Arrange + $event = new Event($this->id, 'php -i'); + $event->days(1, 3); + /** @var callable $methodCall */ + $methodCall = [$event, $method]; + $methodCallClosure = \Closure::fromCallable($methodCall); + + $expressionParts = \explode(' ', $expectedCronExpression); + $dayOfWeekPosition = \count($expressionParts) - 1; + $expressionParts[$dayOfWeekPosition] = '1,3'; + $expectedExpression = \implode(' ', $expressionParts); + + // Act + $methodCallClosure(); + + // Assert + self::assertSame($expectedExpression, $event->getExpression()); + } + public function test_hourly_at_with_valid_minute(): void { // Arrange