<?php
namespace addons\crontab\controller;
use app\common\model\Crontab;
use Cron\CronExpression;
use fast\Http;
use think\Controller;
use think\Db;
use think\Exception;
use think\Log;
class Autotask extends Controller
{
public function _initialize()
{
if (!$this->request->isCli())
$this->error('Autotask script only work at client!');
parent::_initialize();
error_reporting(0);
set_time_limit(0);
}
public function index()
{
$time = time();
$logDir = LOG_PATH . 'crontab/';
if (!is_dir($logDir)) {
mkdir($logDir, 0755);
}
$crontabList = Crontab::where('status', '=', 'normal')->order('weigh desc,id desc')->select();
$execTime = time();
foreach ($crontabList as $crontab) {
$update = [];
$execute = FALSE;
if ($time < $crontab['begintime']) {
continue;
}
if ($crontab['maximums'] && $crontab['executes'] > $crontab['maximums']) {
$update['status'] = 'completed';
} else if ($crontab['endtime'] > 0 && $time > $crontab['endtime']) {
$update['status'] = 'expired';
} else {
$cron = CronExpression::factory($crontab['schedule']);
if (!$cron->isDue(date("YmdHi", $execTime)) || date("YmdHi", $execTime) === date("YmdHi", $crontab['executetime']))
continue;
$execute = TRUE;
}
if ($execute) {
$update['executetime'] = $time;
$update['executes'] = $crontab['executes'] + 1;
$update['status'] = ($crontab['maximums'] > 0 && $update['executes'] >= $crontab['maximums']) ? 'completed' : 'normal';
}
if (!$update)
continue;
$crontab->save($update);
if (!$execute)
continue;
try {
if ($crontab['type'] == 'url') {
if (substr($crontab['content'], 0, 1) == "/") {
exec('nohup php ' . ROOT_PATH . 'public/index.php ' . $crontab['content'] . ' >> ' . $logDir . date("Y-m-d") . '.log 2>&1 &');
} else {
Http::sendAsyncRequest($crontab['content']);
}
} else if ($crontab['type'] == 'sql') {
$connect = Db::connect([], true);
$connect->execute("select 1");
$connect->getPdo()->exec($crontab['content']);
} else if ($crontab['type'] == 'shell') {
exec($crontab['content'] . ' >> ' . $logDir . date("Y-m-d") . '.log 2>&1 &');
}
} catch (Exception $e) {
Log::record($e->getMessage());
}
}
return 'Execute completed!';
}
}