X-Git-Url: https://git.stricted.de/?a=blobdiff_plain;f=wcfsetup%2Finstall%2Ffiles%2Flib%2Fdata%2Fcronjob%2FCronjobAction.class.php;h=fdc3e6678c917ca1e45c8406b186b62d04ca4568;hb=13b11e4c70585510ecf147983a69955fe4590ef9;hp=6cafb1197b4f7bff85a22b76bd6b8f70aabd4a7e;hpb=cd3319c04a81b264937bee2fc6ef0b80bfe0f823;p=GitHub%2FWoltLab%2FWCF.git diff --git a/wcfsetup/install/files/lib/data/cronjob/CronjobAction.class.php b/wcfsetup/install/files/lib/data/cronjob/CronjobAction.class.php index 6cafb1197b..fdc3e6678c 100644 --- a/wcfsetup/install/files/lib/data/cronjob/CronjobAction.class.php +++ b/wcfsetup/install/files/lib/data/cronjob/CronjobAction.class.php @@ -1,10 +1,12 @@ - * @package WoltLabSuite\Core\Data\Cronjob - * - * @method Cronjob create() - * @method CronjobEditor[] getObjects() - * @method CronjobEditor getSingleObject() + * + * @author Tim Duesterhus, Alexander Ebert + * @copyright 2001-2019 WoltLab GmbH + * @license GNU Lesser General Public License + * @package WoltLabSuite\Core\Data\Cronjob + * + * @method Cronjob create() + * @method CronjobEditor[] getObjects() + * @method CronjobEditor getSingleObject() */ -class CronjobAction extends AbstractDatabaseObjectAction implements IToggleAction { - use TDatabaseObjectToggle; - - /** - * @inheritDoc - */ - protected $className = CronjobEditor::class; - - /** - * @inheritDoc - */ - protected $permissionsCreate = ['admin.management.canManageCronjob']; - - /** - * @inheritDoc - */ - protected $permissionsDelete = ['admin.management.canManageCronjob']; - - /** - * @inheritDoc - */ - protected $permissionsUpdate = ['admin.management.canManageCronjob']; - - /** - * @inheritDoc - */ - protected $allowGuestAccess = ['executeCronjobs']; - - /** - * @inheritDoc - */ - protected $requireACP = ['create', 'delete', 'update', 'toggle', 'execute']; - - /** - * @inheritDoc - */ - public function validateDelete() { - parent::validateDelete(); - - foreach ($this->getObjects() as $cronjob) { - if (!$cronjob->isDeletable()) { - throw new PermissionDeniedException(); - } - } - } - - /** - * @inheritDoc - */ - public function validateUpdate() { - parent::validateUpdate(); - - foreach ($this->getObjects() as $cronjob) { - if (!$cronjob->isEditable()) { - throw new PermissionDeniedException(); - } - } - } - - /** - * @inheritDoc - */ - public function validateToggle() { - parent::validateUpdate(); - - foreach ($this->getObjects() as $cronjob) { - if (!$cronjob->canBeDisabled()) { - throw new PermissionDeniedException(); - } - } - } - - /** - * Validates the 'execute' action. - */ - public function validateExecute() { - parent::validateUpdate(); - } - - /** - * Executes cronjobs. - */ - public function execute() { - $return = []; - - // switch session owner to 'system' during execution of cronjobs - $actualUser = WCF::getUser(); - WCF::getSession()->changeUser(new User(null, ['userID' => 0, 'username' => 'System']), true); - WCF::getSession()->disableUpdate(); - - try { - foreach ($this->getObjects() as $key => $cronjob) { - // mark them as pending - $cronjob->update(['state' => Cronjob::PENDING]); - } - - foreach ($this->getObjects() as $cronjob) { - // it now time for executing - $cronjob->update(['state' => Cronjob::EXECUTING]); - $className = $cronjob->className; - - /** @var ICronjob $executable */ - $executable = new $className(); - - // execute cronjob - $exception = null; - - // check if all required options are set for cronjob to be executed - // note: a general log is created to avoid confusion why a cronjob - // apparently is not executed while that is indeed the correct internal - // behavior - if ($cronjob->validateOptions()) { - try { - $executable->execute(new Cronjob($cronjob->cronjobID)); - } - catch (\Exception $exception) { } - } - - CronjobLogEditor::create([ - 'cronjobID' => $cronjob->cronjobID, - 'execTime' => TIME_NOW, - 'success' => $exception ? 0 : 1, - 'error' => $exception ? $exception->getMessage() : '' - ]); - - // calculate next exec-time - $nextExec = $cronjob->getNextExec(); - $data = [ - 'lastExec' => TIME_NOW, - 'nextExec' => $nextExec, - 'afterNextExec' => $cronjob->getNextExec($nextExec + 120) - ]; - - // cronjob failed - if ($exception) { - if ($cronjob->failCount < Cronjob::MAX_FAIL_COUNT) { - $data['failCount'] = $cronjob->failCount + 1; - } - - // cronjob failed too often: disable it - if ($cronjob->failCount + 1 == Cronjob::MAX_FAIL_COUNT) { - $data['isDisabled'] = 1; - } - } - // if no error: reset fail counter - else { - $data['failCount'] = 0; - - // if cronjob has been disabled because of too many - // failed executions, enable it again - if ($cronjob->failCount == Cronjob::MAX_FAIL_COUNT && $cronjob->isDisabled) { - $data['isDisabled'] = 0; - } - } - - $cronjob->update($data); - - // build the return value - if ($exception === null && !$cronjob->isDisabled) { - $dateTime = DateUtil::getDateTimeByTimestamp($nextExec); - $return[$cronjob->cronjobID] = [ - 'time' => $nextExec, - 'formatted' => str_replace( - '%time%', - DateUtil::format($dateTime, DateUtil::TIME_FORMAT), - str_replace( - '%date%', - DateUtil::format($dateTime, DateUtil::DATE_FORMAT), - WCF::getLanguage()->get('wcf.date.dateTimeFormat') - ) - ) - ]; - } - - // we are finished - $cronjob->update(['state' => Cronjob::READY]); - - // throw exception again to show error message - if ($exception) { - throw $exception; - } - } - } - finally { - // switch session back to the actual user - WCF::getSession()->changeUser($actualUser, true); - } - - return $return; - } - - /** - * Validates the 'executeCronjobs' action. - */ - public function validateExecuteCronjobs() { - // does nothing - } - - /** - * Executes open cronjobs. - */ - public function executeCronjobs() { - // switch session owner to 'system' during execution of cronjobs - WCF::getSession()->changeUser(new User(null, ['userID' => 0, 'username' => 'System']), true); - WCF::getSession()->disableUpdate(); - - CronjobScheduler::getInstance()->executeCronjobs(); - } +class CronjobAction extends AbstractDatabaseObjectAction implements IToggleAction +{ + use TDatabaseObjectToggle; + + /** + * @inheritDoc + */ + protected $className = CronjobEditor::class; + + /** + * @inheritDoc + */ + protected $permissionsCreate = ['admin.management.canManageCronjob']; + + /** + * @inheritDoc + */ + protected $permissionsDelete = ['admin.management.canManageCronjob']; + + /** + * @inheritDoc + */ + protected $permissionsUpdate = ['admin.management.canManageCronjob']; + + /** + * @inheritDoc + */ + protected $allowGuestAccess = ['executeCronjobs']; + + /** + * @inheritDoc + */ + protected $requireACP = ['create', 'delete', 'update', 'toggle', 'execute']; + + /** + * @inheritDoc + */ + public function validateDelete() + { + parent::validateDelete(); + + foreach ($this->getObjects() as $cronjob) { + if (!$cronjob->isDeletable()) { + throw new PermissionDeniedException(); + } + } + } + + /** + * @inheritDoc + */ + public function validateUpdate() + { + parent::validateUpdate(); + + foreach ($this->getObjects() as $cronjob) { + if (!$cronjob->isEditable()) { + throw new PermissionDeniedException(); + } + } + } + + /** + * @inheritDoc + */ + public function validateToggle() + { + parent::validateUpdate(); + + foreach ($this->getObjects() as $cronjob) { + if (!$cronjob->canBeDisabled()) { + throw new PermissionDeniedException(); + } + } + } + + /** + * Validates the 'execute' action. + */ + public function validateExecute() + { + parent::validateUpdate(); + } + + /** + * Executes cronjobs. + */ + public function execute() + { + $return = []; + + // switch session owner to 'system' during execution of cronjobs + $actualUser = WCF::getUser(); + WCF::getSession()->changeUser(new User(null, ['userID' => 0, 'username' => 'System']), true); + WCF::getSession()->disableUpdate(); + + try { + foreach ($this->getObjects() as $cronjob) { + // mark them as pending + $cronjob->update(['state' => Cronjob::PENDING]); + } + + foreach ($this->getObjects() as $cronjob) { + // it now time for executing + $cronjob->update(['state' => Cronjob::EXECUTING]); + $className = $cronjob->className; + + /** @var ICronjob $executable */ + $executable = new $className(); + + // execute cronjob + $exception = null; + + // check if all required options are set for cronjob to be executed + // note: a general log is created to avoid confusion why a cronjob + // apparently is not executed while that is indeed the correct internal + // behavior + if ($cronjob->validateOptions()) { + try { + $executable->execute(new Cronjob($cronjob->cronjobID)); + } catch (\Exception $exception) { + } + } + + CronjobLogEditor::create([ + 'cronjobID' => $cronjob->cronjobID, + 'execTime' => TIME_NOW, + 'success' => $exception ? 0 : 1, + 'error' => $exception ? $exception->getMessage() : '', + ]); + + // calculate next exec-time + $nextExec = $cronjob->getNextExec(); + $data = [ + 'lastExec' => TIME_NOW, + 'nextExec' => $nextExec, + 'afterNextExec' => $cronjob->getNextExec($nextExec + 120), + ]; + + // cronjob failed + if ($exception) { + if ($cronjob->failCount < Cronjob::MAX_FAIL_COUNT) { + $data['failCount'] = $cronjob->failCount + 1; + } + + // cronjob failed too often: disable it + if ($cronjob->failCount + 1 == Cronjob::MAX_FAIL_COUNT) { + $data['isDisabled'] = 1; + } + } // if no error: reset fail counter + else { + $data['failCount'] = 0; + + // if cronjob has been disabled because of too many + // failed executions, enable it again + if ($cronjob->failCount == Cronjob::MAX_FAIL_COUNT && $cronjob->isDisabled) { + $data['isDisabled'] = 0; + } + } + + $cronjob->update($data); + + // build the return value + if ($exception === null && !$cronjob->isDisabled) { + $dateTime = DateUtil::getDateTimeByTimestamp($nextExec); + $return[$cronjob->cronjobID] = [ + 'time' => $nextExec, + 'formatted' => \str_replace( + '%time%', + DateUtil::format($dateTime, DateUtil::TIME_FORMAT), + \str_replace( + '%date%', + DateUtil::format($dateTime, DateUtil::DATE_FORMAT), + WCF::getLanguage()->get('wcf.date.dateTimeFormat') + ) + ), + ]; + } + + // we are finished + $cronjob->update(['state' => Cronjob::READY]); + + // throw exception again to show error message + if ($exception) { + throw $exception; + } + } + } finally { + // switch session back to the actual user + WCF::getSession()->changeUser($actualUser, true); + } + + return $return; + } + + /** + * Validates the 'executeCronjobs' action. + */ + public function validateExecuteCronjobs() + { + // does nothing + } + + /** + * Executes open cronjobs. + */ + public function executeCronjobs() + { + // switch session owner to 'system' during execution of cronjobs + WCF::getSession()->changeUser(new User(null, ['userID' => 0, 'username' => 'System']), true); + WCF::getSession()->disableUpdate(); + + CronjobScheduler::getInstance()->executeCronjobs(); + } }