From: Tim Düsterhus Date: Thu, 4 Aug 2022 12:08:18 +0000 (+0200) Subject: Replace use of CronjobUtil by dragonmantank/cron-expression X-Git-Tag: 6.0.0_Alpha_1~1078^2~1 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=b355b1c75179f724cb0353247ce9b0b0f4712975;p=GitHub%2FWoltLab%2FWCF.git Replace use of CronjobUtil by dragonmantank/cron-expression --- diff --git a/wcfsetup/install/files/lib/acp/form/CronjobAddForm.class.php b/wcfsetup/install/files/lib/acp/form/CronjobAddForm.class.php index 5715882905..309d1db16b 100755 --- a/wcfsetup/install/files/lib/acp/form/CronjobAddForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/CronjobAddForm.class.php @@ -2,16 +2,16 @@ 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; /** @@ -149,22 +149,21 @@ class CronjobAddForm extends AbstractForm } } - 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'); } } diff --git a/wcfsetup/install/files/lib/data/cronjob/Cronjob.class.php b/wcfsetup/install/files/lib/data/cronjob/Cronjob.class.php index 75cc6fb31f..8cf510251c 100644 --- a/wcfsetup/install/files/lib/data/cronjob/Cronjob.class.php +++ b/wcfsetup/install/files/lib/data/cronjob/Cronjob.class.php @@ -2,10 +2,10 @@ 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. @@ -70,9 +70,8 @@ class Cronjob extends DatabaseObject * 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) { @@ -86,14 +85,20 @@ class Cronjob extends DatabaseObject } } - 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(); } /** diff --git a/wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php index 0c992381f1..3cc0768aae 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php @@ -2,6 +2,8 @@ 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; @@ -10,7 +12,6 @@ use wcf\system\database\util\PreparedStatementConditionBuilder; 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; @@ -21,7 +22,6 @@ use wcf\system\form\builder\field\validation\FormFieldValidator; use wcf\system\form\builder\IFormDocument; use wcf\system\language\LanguageFactory; use wcf\system\WCF; -use wcf\util\CronjobUtil; use wcf\util\StringUtil; /** @@ -134,13 +134,14 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu */ 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'] - ); + )); } /** @@ -261,6 +262,7 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu ->value(true), ]); + $fieldFactory = new FieldFactory(); foreach (['startMinute', 'startHour', 'startDom', 'startMonth', 'startDow'] as $timeProperty) { $dataContainer->insertBefore( TextFormField::create($timeProperty) @@ -270,10 +272,16 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu ->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',