<?php
if(!defined( 'MOD' ))die("access die");
$action = $_GET['action'] ? $_GET['action'] : 'manage';
switch($action){
	case 'manage':
		$data = qdb::fetchAll("select * from ".TABLEPRE."cron ");
		foreach($data as &$val){
			$val['filter'] = implode(' , ', unserialize($val['filter']));
		}
		unset($val);
	break;
	
	case 'add':
	case 'modify':
		if($action == 'modify'){
			$id = intval($_GET['id']);
			$_output = qdb::queryFirst("select * from ".TABLEPRE."cron where id = '{$id}'");
			if(empty($_output))  qbase::purviewCheckDie('error request');
			$_output['filter'] = unserialize($_output['filter']);
		}	
		if($_POST['myFormAc'] == 'update'){
			$param = array();
			$param['name'] = trim($_POST['name']);
			if(empty($param['name'])) qbase::purviewCheckDie('需要填写名称');
			if(!preg_match("/[a-zA-Z0-9\-\_]{1,63}\.php/", $param['name'])) qbase::purviewCheckDie('文件名不符合规则');
			$file = R_P . "/include/cron/" . $param['name'];
			if(!is_file($file)) qbase::purviewCheckDie('执行程序不存在，请先上传');
			$param['title'] = trim($_POST['title']);
			$param['status'] = intval($_POST['status']);
			$filter = cronTimeFormat(is_array($_POST['filter']) ? $_POST['filter'] : array());
			if($filter === false) qbase::purviewCheckDie('出错了，程序执行规则不符合');
			$param['filter'] = addslashes(stripslashes(serialize($filter)));
			if($action == 'add'){
				$param['createdate'] = time();
				$sql = qbase::createSql(TABLEPRE.'cron', $param, 'insert');
				qdb::query($sql);
			}else{
				$sql = qbase::createSql(TABLEPRE.'cron', $param, 'update') . " where id = '{$id}' ";
				qdb::query($sql);
			}
			qbase::showmsg('操作成功', 'default', 'system.php?sys=cron');
		}
	break;
	
	case 'delete':
		if($admin_info['groupid'] > 2 ) qbase::purviewCheckDie();
		checkAdminReferer();
		$id = intval($_GET['id']);
		qdb::query("delete from ".TABLEPRE."cron where id = '{$id}' ");
		qbase::showmsg('操作成功', 'default', 'system.php?sys=cron');
	break;
	
	case 'run':
		if(!AJAX) qbase::purviewCheckDie('error request');
		$id = intval($_GET['id']);
		if($id > 0){
			$data = qdb::queryFirst("select * from ".TABLEPRE."cron where id = '{$id}'");
			if(empty($data)) qbase::purviewCheckDie('error request');
			$data = array($data);
		}else{
			$data = qdb::fetchAll("select * from ".TABLEPRE."cron where status > 0 ");
		}
		foreach($data as $val){
			$val['filter'] = @unserialize($val['filter']);
			$file = R_P . "/include/cron/" . $val['name'];
			$name = 'cron_' . substr($val['name'], 0, strrpos($val['name'], '.'));
			if($id > 0){
				if(!is_file($file)) qbase::purviewCheckDie('没有找到该计划任务的执行文件');
				require_once($file);
				if(!class_exists($name)) qbase::purviewCheckDie('执行程序编写不合规范');
				$obj = new $name;
				if(method_exists($obj, 'run')){
					qdb::query("update ".TABLEPRE."cron set lasttime = '".time()."' where id = '{$val['id']}' ");
					$obj->run();
				}else{
					qbase::purviewCheckDie('执行程序编写不合规范');
				}	
				break;
			}else{
				if(empty($val['filter']) || $_SERVER['REQUEST_TIME'] - $val['lasttime'] <= 30) continue;
				$n = 0;
				foreach(array('w','d','h','m') as $v){
					$st = checkFilter($val['filter'], $v);
					if($st === false) break;
					else $n++;
				}
				if($n != 4) continue;
				if(!is_file($file)) continue;
				require_once($file);
				if(!class_exists($name)) continue;
				$obj = new $name;
				if(method_exists($obj, 'run')){
					qdb::query("update ".TABLEPRE."cron set lasttime = '".time()."' where id = '{$val['id']}' ");
					$obj->run();
				}
			}
		}
		$time = time();
		$r = array('status'=>200, 'dateline'=>$time, 'h'=>intval(qbase::formatTime('G', $time)), 'm'=>intval(qbase::formatTime('i', $time)));
		echo qbase::xmlPrint(qbase::jsonencode($r));
		exit();
	break;
	
	default:
		qbase::purviewCheckDie('error request');
	break;
}

include qbase::template($path . 'cron');

function checkFilter(&$filter, $type){
	$d = $filter[$type];
	$t = 0;
	switch($type){
		case 'w':
			$t = qbase::formatTime('w', $_SERVER['REQUEST_TIME']) + 1;
		break;
		
		case 'd':
			$t = qbase::formatTime('z', $_SERVER['REQUEST_TIME']);
		break;		
		
		case 'h':
			$t = qbase::formatTime('G', $_SERVER['REQUEST_TIME']);
		break;		

		case 'm':
			$t = qbase::formatTime('i', $_SERVER['REQUEST_TIME']);
			$t = intval($t);
		break;			
	}
	if(strpos($d, '*/') === 0){
		$d = intval(substr($d, 2));
		return $d === 0 ? false : ($t % $d === 0 ? true : false);
	}elseif($d === '*'){
		return true;
	}elseif(intval($d) === intval($t)){
		return true;
	}else{
		return false;
	}	
}

function cronTimeFormat($filter){
	/*m,h,d,w*/
	$index = 0;
	$format = array(
		'm'=>array(1,60),
		'h'=>array(1,24),
		'd'=>array(1,366),
		'w'=>array(1,7)
	);
	foreach($format as $key=>$val){
		if(!isset($filter[$key])) return false;
	}
	foreach($filter as $key=>$val){
		if(!isset($format[$key])) return false;
		$p = cronTimeFormatV($val, $format[$key][0], $format[$key][1]);
		if($p === false) return false;
		$filter[$key] = $p;
	}
	return $filter;
}

function cronTimeFormatV($t, $min, $max){
	if(strpos($t, '*/') === 0){
		$temp = explode('/', $t);
		if(count($temp) != 2) return false;
		$temp[1] = intval($temp[1]);
		if($temp[1] >= $min && $temp[1] <= $max) return '*/' . $temp[1];
		else return false;
	}elseif($t === '*'){
		return '*';
	}else{
		$t = intval($t);
		if($t >= $min && $t <= $max) return $t;
		else return false;	
	}
}
?>
