xxb/module/cron/control.php
2023-10-23 15:51:36 +08:00

223 lines
7.5 KiB
PHP

<?php
/**
* The control file of cron of XXB.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd., www.zentao.net)
* @license ZOSL (https://zpl.pub/page/zoslv1.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package cron
* @version $Id$
* @link https://xuanim.com
*/
class cron extends control
{
/**
* Index page.
*
* @access public
* @return void
*/
public function index()
{
$this->lang->menuGroups->cron = 'system';
$this->lang->cron->menu = $this->lang->system->menu;
$this->lang->cron->menuOrder = $this->lang->system->menuOrder;
$this->view->title = $this->lang->cron->common;
$this->view->crons = $this->cron->getCrons();
$this->display();
}
/**
* Turnon cron.
*
* @access public
* @return void
*/
public function turnon($confirm = 'no')
{
$turnon = empty($this->config->global->cron) ? 1 : 0;
if(!$turnon and $confirm == 'no') die(js::confirm($this->lang->cron->confirmTurnon, inlink('turnon', "confirm=yes")) . js::reload('parent'));
$this->loadModel('setting')->setItem('system.sys.common.global.cron', $turnon);
die(js::reload('parent'));
}
/**
* Create cron.
*
* @access public
* @return void
*/
public function create()
{
if($_POST)
{
$this->cron->create();
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('index')));
}
$this->view->title = $this->lang->cron->create . $this->lang->cron->common;
$this->display();
}
/**
* Edit cron.
*
* @param int $cronID
* @access public
* @return void
*/
public function edit($cronID)
{
if($_POST)
{
$this->cron->update($cronID);
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('index')));
}
$this->view->title = $this->lang->cron->edit . $this->lang->cron->common;
$this->view->cron = $this->cron->getById($cronID);
$this->display();
}
/**
* Toggle run cron.
*
* @param int $cronID
* @param int $status
* @access public
* @return void
*/
public function toggle($cronID, $status)
{
$this->cron->changeStatus($cronID, $status);
$this->locate(inlink('index'));
}
/**
* Delete cron.
*
* @param int $cronID
* @param string $confirm
* @access public
* @return void
*/
public function delete($cronID, $confirm = 'no')
{
$this->dao->delete()->from(TABLE_CRON)->where('id')->eq($cronID)->exec();
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::Error()));
$this->send(array('result' => 'success'));
}
/**
* Ajax exec cron.
*
* @access public
* @return void
*/
public function ajaxExec()
{
ignore_user_abort(true);
set_time_limit(0);
session_write_close();
/* Check cron turnon. */
if(empty($this->config->global->cron)) die();
/* make cron status to running. */
$configID = $this->cron->getConfigID();
$configID = $this->cron->markCronStatus('running', $configID);
/* Get and parse crons. */
$crons = $this->cron->getCrons('nostop');
$parsedCrons = $this->cron->parseCron($crons);
/* Update last time. */
$this->cron->changeStatus(key($parsedCrons), 'normal', true);
$startedTime = time();
while(true)
{
dao::$cache = array();
/* When cron is null then die. */
if(empty($crons)) break;
if(empty($parsedCrons)) break;
if(!$this->config->global->cron) break;
/* Run crons. */
$now = new datetime('now');
foreach($parsedCrons as $id => $cron)
{
$cronInfo = $this->cron->getById($id);
/* Skip empty and stop cron.*/
if(empty($cronInfo) or $cronInfo->status == 'stop') continue;
/* Skip cron that status is running and run time is less than max. */
if($cronInfo->status == 'running' and (time() - strtotime($cronInfo->lastTime)) < $this->config->cron->maxRunTime) continue;
/* Skip cron that last time is more than this cron time. */
if($cronInfo->lastTime > $cron['time']->format(DT_DATETIME1)) die();
if($now > $cron['time'])
{
$this->cron->changeStatus($id, 'running');
$parsedCrons[$id]['time'] = $cron['cron']->getNextRunDate();
/* Execution command. */
$output = '';
$return = '';
if($cron['command'])
{
if(isset($crons[$id]) and $crons[$id]->type == 'ranzhi')
{
parse_str($cron['command'], $customParams);
unset($customParams['moduleName']);
unset($customParams['methodName']);
unset($customParams['appName']);
parse_str($cron['command'], $params);
if(isset($params['moduleName']) and isset($params['methodName']) and isset($params['appName']))
{
$output = $this->fetch($params['moduleName'], $params['methodName'], $customParams, $params['appName']);
}
}
elseif(isset($crons[$id]) and $crons[$id]->type == 'system')
{
exec($cron['command'], $output, $return);
if($output) $output = join("\n", $output);
}
/* Save log. */
$log = '';
$time = $now->format('G:i:s');
$log = "$time task " . $id . " executed,\ncommand: $cron[command].\nreturn : $return.\noutput : $output\n";
$this->cron->logCron($log);
unset($log);
}
/* Revert cron status. */
$this->cron->changeStatus($id, 'normal');
}
}
/* Check whether the task change. */
$newCrons = $this->cron->getCrons('nostop');
$changed = $this->cron->checkChange();
if(count($newCrons) != count($crons) or $changed)
{
$crons = $newCrons;
$parsedCrons = $this->cron->parseCron($newCrons);
}
/* Sleep some seconds. */
$sleepTime = 60 - ((time() - $now->getTimestamp()) % 60);
sleep($sleepTime);
/* Break while. */
if(connection_status() != CONNECTION_NORMAL) break;
if(((time() - $startedTime) / 3600 / 24) >= $this->config->cron->maxRunDays) break;
}
/* Revert cron status to stop. */
$this->cron->markCronStatus('stop', $configID);
}
}