namespace wcf\acp\form;
+use Cron\CronExpression;
+use Cron\FieldFactory;
use wcf\data\cronjob\Cronjob;
use wcf\data\cronjob\CronjobAction;
use wcf\data\cronjob\CronjobEditor;
use wcf\form\AbstractForm;
-use wcf\system\exception\SystemException;
use wcf\system\exception\UserInputException;
use wcf\system\language\I18nHandler;
use wcf\system\request\LinkHandler;
use wcf\system\WCF;
-use wcf\util\CronjobUtil;
use wcf\util\StringUtil;
/**
}
}
- try {
- CronjobUtil::validate(
- $this->startMinute,
- $this->startHour,
- $this->startDom,
- $this->startMonth,
- $this->startDow
- );
- } catch (SystemException $e) {
- // extract field name
- $fieldName = '';
- if (\preg_match("/cronjob attribute '(.*)'/", $e->getMessage(), $match)) {
- $fieldName = $match[1];
- }
-
- throw new UserInputException($fieldName, 'invalid');
+ $fieldFactory = new FieldFactory();
+ if (!$fieldFactory->getField(CronExpression::MINUTE)->validate($this->startMinute)) {
+ throw new UserInputException('startMinute', 'invalid');
+ }
+ if (!$fieldFactory->getField(CronExpression::HOUR)->validate($this->startHour)) {
+ throw new UserInputException('startHour', 'invalid');
+ }
+ if (!$fieldFactory->getField(CronExpression::DAY)->validate($this->startDom)) {
+ throw new UserInputException('startDom', 'invalid');
+ }
+ if (!$fieldFactory->getField(CronExpression::MONTH)->validate($this->startMonth)) {
+ throw new UserInputException('startMonth', 'invalid');
+ }
+ if (!$fieldFactory->getField(CronExpression::WEEKDAY)->validate($this->startDow)) {
+ throw new UserInputException('startDow', 'invalid');
}
}
namespace wcf\data\cronjob;
+use Cron\CronExpression;
use wcf\data\DatabaseObject;
use wcf\data\TDatabaseObjectOptions;
use wcf\system\WCF;
-use wcf\util\CronjobUtil;
/**
* Represents a cronjob.
* Returns timestamp of next execution.
*
* @param int $timeBase
- * @return int
*/
- public function getNextExec($timeBase = null)
+ public function getNextExec($timeBase = null): int
{
if ($timeBase === null) {
if ($this->lastExec) {
}
}
- return CronjobUtil::calculateNextExec(
+ $dateTime = (new \DateTimeImmutable("@{$timeBase}"))
+ // The TZ parameter in the constructor is ignored for timestamps.
+ ->setTimezone(new \DateTimeZone(TIMEZONE));
+
+ $expression = new CronExpression(\sprintf(
+ '%s %s %s %s %s',
$this->startMinute,
$this->startHour,
$this->startDom,
$this->startMonth,
$this->startDow,
- $timeBase
- );
+ ));
+
+ return $expression->getNextRunDate($dateTime)->getTimestamp();
}
/**
namespace wcf\system\package\plugin;
+use Cron\CronExpression;
+use Cron\FieldFactory;
use wcf\data\cronjob\Cronjob;
use wcf\data\cronjob\CronjobEditor;
use wcf\data\cronjob\CronjobList;
use wcf\system\devtools\pip\IDevtoolsPipEntryList;
use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
-use wcf\system\exception\SystemException;
use wcf\system\form\builder\container\IFormContainer;
use wcf\system\form\builder\field\BooleanFormField;
use wcf\system\form\builder\field\ClassNameFormField;
use wcf\system\form\builder\IFormDocument;
use wcf\system\language\LanguageFactory;
use wcf\system\WCF;
-use wcf\util\CronjobUtil;
use wcf\util\StringUtil;
/**
*/
protected function validateImport(array $data)
{
- CronjobUtil::validate(
- $data['startMinute'],
+ // The constructor will throw if the expression is not valid.
+ new CronExpression(\sprintf(
+ '%s %s %s %s %s',
$data['startHour'],
$data['startDom'],
$data['startMonth'],
$data['startDow']
- );
+ ));
}
/**
->value(true),
]);
+ $fieldFactory = new FieldFactory();
foreach (['startMinute', 'startHour', 'startDom', 'startMonth', 'startDow'] as $timeProperty) {
$dataContainer->insertBefore(
TextFormField::create($timeProperty)
->required()
->addValidator(new FormFieldValidator(
'format',
- static function (TextFormField $formField) use ($timeProperty) {
- try {
- CronjobUtil::validateAttribute($timeProperty, $formField->getSaveValue());
- } catch (SystemException $e) {
+ static function (TextFormField $formField) use ($timeProperty, $fieldFactory) {
+ $position = match ($timeProperty) {
+ 'startMinute' => CronExpression::MINUTE,
+ 'startHour' => CronExpression::HOUR,
+ 'startDom' => CronExpression::MONTH,
+ 'startMonth' => CronExpression::MONTH,
+ 'startDow' => CronExpression::WEEKDAY,
+ };
+
+ if (!$fieldFactory->getField($position)->validate($formField->getSaveValue())) {
$formField->addValidationError(
new FormFieldValidationError(
'format',