diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /lib/models/CronjobSchedule.class.php | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/models/CronjobSchedule.class.php')
| -rw-r--r-- | lib/models/CronjobSchedule.class.php | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/lib/models/CronjobSchedule.class.php b/lib/models/CronjobSchedule.class.php deleted file mode 100644 index 4304be1..0000000 --- a/lib/models/CronjobSchedule.class.php +++ /dev/null @@ -1,324 +0,0 @@ -<?php -// +---------------------------------------------------------------------------+ -// This file is part of Stud.IP -// CronjobSchedule.class.php -// -// Copyright (C) 2013 Jan-Hendrik Willms <tleilax+studip@gmail.com> -// +---------------------------------------------------------------------------+ -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or any later version. -// +---------------------------------------------------------------------------+ -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// +---------------------------------------------------------------------------+ - -/** - * CronjobSchedule - Model for the database table "cronjobs_schedules" - * - * @author Jan-Hendrik Willms <tleilax+studip@gmail.com> - * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 - * @category Stud.IP - * @since 2.4 - * - * @property string $id alias column for schedule_id - * @property string $schedule_id database column - * @property string $task_id database column - * @property int $active database column - * @property string|null $title database column - * @property string|null $description database column - * @property string|null $parameters database column - * @property string $priority database column - * @property string $type database column - * @property int|null $minute database column - * @property int|null $hour database column - * @property int|null $day database column - * @property int|null $month database column - * @property int|null $day_of_week database column - * @property int $next_execution database column - * @property int|null $last_execution database column - * @property string|null $last_result database column - * @property int $execution_count database column - * @property int $mkdate database column - * @property int $chdate database column - * @property SimpleORMapCollection|CronjobLog[] $logs has_many CronjobLog - * @property CronjobTask $task belongs_to CronjobTask - */ - -class CronjobSchedule extends SimpleORMap -{ - const PRIORITY_LOW = 'low'; - const PRIORITY_NORMAL = 'normal'; - const PRIORITY_HIGH = 'high'; - - protected static function configure($config = []) - { - $config['db_table'] = 'cronjobs_schedules'; - - $config['belongs_to']['task'] = [ - 'class_name' => CronjobTask::class, - 'foreign_key' => 'task_id', - ]; - $config['has_many']['logs'] = [ - 'class_name' => CronjobLog::class, - 'on_delete' => 'delete', - 'on_store' => 'store', - ]; - - $config['registered_callbacks']['before_store'][] = 'cbJsonifyParameters'; - $config['registered_callbacks']['after_store'][] = 'cbJsonifyParameters'; - $config['registered_callbacks']['after_initialize'][] = 'cbJsonifyParameters'; - - parent::configure($config); - } - - /** - * Returns a mapped version of the priorities (key = priority value, - * value = localized priority label). - * - * @return Array The mapped priorities - */ - public static function getPriorities() - { - $mapping = []; - $mapping[self::PRIORITY_LOW] = _('niedrig'); - $mapping[self::PRIORITY_NORMAL] = _('normal'); - $mapping[self::PRIORITY_HIGH] = _('hoch'); - - return $mapping; - } - - /** - * Maps a priority value to it's localized label. - * - * @param String $priority Priority value - * @return String The localized label - * @throws RuntimeException when an unknown priority value is passed - */ - public static function describePriority($priority) - { - $priority = $priority ?? 'normal'; - - $mapping = self::getPriorities(); - if (!isset($mapping[$priority])) { - throw new RuntimeException('Access to unknown priority "' . $priority . '"'); - } - - return $mapping[$priority]; - } - - /** - * replaces title with task name if title is empty. - * - * @return string the title or the task name - */ - public function getTitle() - { - return $this->content['title'] ?: $this->task->name ?? ''; - } - - protected function cbJsonifyParameters($type) - { - if ($type === 'before_store' && !is_string($this->parameters)) { - $this->parameters = json_encode($this->parameters ?: null); - } - if (in_array($type, ['after_initialize', 'after_store']) && is_string($this->parameters)) { - $parameters = json_decode($this->parameters, true) ?: []; - if ($this->task && $this->task->valid) { - $default_parameters = $this->task->extractDefaultParameters(); - foreach ($default_parameters as $key => $value) { - if (!isset($parameters[$key])) { - $parameters[$key] = $value; - } - } - } - $this->parameters = $parameters; - } - } - - /** - * Stores the schedule in database. Will bail out with an exception if - * the provided task does not exists. Will also nullify the title if it - * matches the task name (see CronjobSchedule::getTitle()). - * - * @return CronjobSchedule Returns itself to allow chaining - */ - public function store() - { - if ($this->task === null) { - $message = sprintf('A task with the id "%s" does not exist.', $this->task_id); - throw new InvalidArgumentException($message); - } - - // Remove title if it is the default (task's name) - if ($this->title === $this->task->name) { - $this->title = null; - } - - parent::store(); - - return $this; - } - - /** - * Activates this schedule. - * - * @return CronjobSchedule Returns itself to allow chaining - */ - public function activate() - { - $this->active = 1; - $this->next_execution = $this->calculateNextExecution(); - $this->store(); - - return $this; - } - - /** - * Deactivates this schedule. - * - * @return CronjobSchedule Returns itself to allow chaining - */ - public function deactivate() - { - $this->active = 0; - $this->store(); - - return $this; - } - - /** - * Executes this schedule. - * - * @param bool $force Pass true to force execution of the schedule even - * if it's not activated - * @return mixed The result of the execution - * @throws RuntimeException When either the schedule or the according is - * not activated - */ - public function execute($force = false) - { - if (!$force && !$this->active) { - throw new RuntimeException('Execution aborted. Schedule is not active'); - } - if (!$this->task->active) { - throw new RuntimeException('Execution aborted. Associated task is not active'); - } - - $this->last_execution = time(); - $this->execution_count += 1; - $this->next_execution = $this->calculateNextExecution(); - $this->store(); - - $this->task->execution_count += 1; - $this->task->store(); - - $result = $this->task->engage($this->last_result, $this->parameters); - - if ($this->type === 'once') { - $this->active = 0; - } - $this->last_result = $result; - $this->store(); - - return $result; - } - - /** - * Determines whether the schedule should execute given the provided - * timestamp. - * - * @param mixed $now Defines the temporal fix point - * @return bool Whether the schedule should execute or not. - */ - public function shouldExecute($now = null) - { - return ($now ?: time()) >= $this->next_execution; - } - - /** - * Calculates the next execution for this schedule. - * - * For schedules of type 'once' the check solely tests whether the - * timestamp has already passed and will return false in that case. - * Otherwise the defined timestamp will be returned. - * - * For schedules of type 'periodic' the next execution - * is calculated by increasing the current timestamp and testing - * whether all conditions match. This is not the best method to test - * and should be optimized sooner or later. - * - * @param mixed $now Defines the temporal fix point - * @return int Timestamp of calculated next execution - * @throws RuntimeException When calculation takes too long (you should - * check the conditions for validity in that case) - */ - public function calculateNextExecution($now = null) - { - $now = $now ?: time(); - - if ($this->type === 'once') { - return $now <= $this->next_execution - ? $this->next_execution - : false; - } - - $result = $now; - $result -= $result % 60; - - $i = 366 * 24 * 60; // Maximum: A year - $offset = 60; - - do { - $result += $offset; - - // TODO: Performance - Adjust result according to conditions - // See http://coderzone.org/library/PHP-PHP-Cron-Parser-Class_1084.htm - $valid = $this->testTimestamp($result, $this->minute, 'i') - && $this->testTimestamp($result, $this->hour, 'H') - && $this->testTimestamp($result, $this->day, 'd') - && $this->testTimestamp($result, $this->month, 'm') - && $this->testTimestamp($result, $this->day_of_week, 'N'); - - } while (!$valid && $i-- > 0); - - if ($i <= 0) { - throw new RuntimeException('No result, current: ' . date('d.m.Y H:i', $result)); - } - - $this->next_execution = $result; - return $result; - } - - /** - * Tests a timestamp against the passed condition. - * - * @param int $timestamp The timestamp to test - * @param mixed $condition Can be either null for "don't care", a positive - * number for an exact moment or a negative number - * for a repeating moment - * @param String $format Format for date() to extract a portion of the - * timestamp - */ - protected function testTimestamp($timestamp, $condition, $format) - { - if ($condition === null) { - return true; - } - - $probe = (int) date($format, $timestamp); - $condition = (int) $condition; - - if ($condition < 0) { - return ($probe % abs($condition)) === 0; - } - - return $probe === $condition; - } -} |
