Merge branch 'master' of github.com:easysoft/zentaopms
Conflicts: module/dev/lang/en.php
This commit is contained in:
@@ -139,6 +139,8 @@ define('TABLE_ACTION', '`' . $config->db->prefix . 'action`');
|
||||
define('TABLE_FILE', '`' . $config->db->prefix . 'file`');
|
||||
define('TABLE_HISTORY', '`' . $config->db->prefix . 'history`');
|
||||
define('TABLE_EXTENSION', '`' . $config->db->prefix . 'extension`');
|
||||
define('TABLE_CRON', '`' . $config->db->prefix . 'cron`');
|
||||
define('TABLE_MAILQUEUE', '`' . $config->db->prefix . 'mailqueue`');
|
||||
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
|
||||
|
||||
$config->objectTables['product'] = TABLE_PRODUCT;
|
||||
|
||||
44
db/update7.0.sql
Normal file
44
db/update7.0.sql
Normal file
@@ -0,0 +1,44 @@
|
||||
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'cron', '0');
|
||||
|
||||
DROP TABLE IF EXISTS `zt_cron`;
|
||||
CREATE TABLE `zt_cron` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`m` varchar(20) NOT NULL,
|
||||
`h` varchar(20) NOT NULL,
|
||||
`dom` varchar(20) NOT NULL,
|
||||
`mon` varchar(20) NOT NULL,
|
||||
`dow` varchar(20) NOT NULL,
|
||||
`command` text NOT NULL,
|
||||
`remark` varchar(255) NOT NULL,
|
||||
`type` varchar(20) NOT NULL,
|
||||
`buildin` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`status` varchar(20) NOT NULL,
|
||||
`lastTime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
TRUNCATE `zt_cron`;
|
||||
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES
|
||||
('*', '*', '*', '*', '*', '', '监控定时任务', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('30', '23', '*', '*', '*', 'moduleName=project&methodName=computeburn', '更新燃尽图', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('0', '1', '*', '*', '*', 'moduleName=report&methodName=remind', '每日任务提醒', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('*/5', '*', '*', '*', '*', 'moduleName=svn&methodName=run', '同步SVN', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('*/5', '*', '*', '*', '*', 'moduleName=git&methodName=run', '同步GIT', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('30', '0', '*', '*', '*', 'moduleName=backup&methodName=backup', '备份数据和附件', 'zentao', 1, 'normal', '0000-00-00 00:00:00'),
|
||||
('*/5', '*', '*', '*', '*', 'moduleName=mail&methodName=asyncSend', '异步发信', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `zt_mailqueue`;
|
||||
CREATE TABLE `zt_mailqueue` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`toList` varchar(255) NOT NULL,
|
||||
`ccList` varchar(255) NOT NULL,
|
||||
`subject` varchar(255) NOT NULL,
|
||||
`body` text NOT NULL,
|
||||
`addedBy` char(30) NOT NULL,
|
||||
`addedDate` datetime NOT NULL,
|
||||
`sendTime` datetime NOT NULL,
|
||||
`status` varchar(10) NOT NULL DEFAULT 'wait',
|
||||
`failReason` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
@@ -17,9 +17,9 @@ class backup extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct();
|
||||
parent::__construct($moduleName, $methodName);
|
||||
|
||||
$this->backupPath = $this->app->getTmpRoot() . 'backup/';
|
||||
if(!is_dir($this->backupPath))
|
||||
@@ -75,31 +75,52 @@ class backup extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function backup()
|
||||
public function backup($reload = 'no')
|
||||
{
|
||||
set_time_limit(0);
|
||||
$fileName = date('YmdHis') . mt_rand(0, 9);
|
||||
$result = $this->backup->backSQL($this->backupPath . $fileName . '.sql.php');
|
||||
if(!$result->result)
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->backup->error->noWritable, $this->backupPath));
|
||||
die(js::reload('parent'));
|
||||
if($reload == 'yes')
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->backup->error->noWritable, $this->backupPath));
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf($this->lang->backup->error->noWritable, $this->backupPath);
|
||||
}
|
||||
}
|
||||
$this->backup->addFileHeader($this->backupPath . $fileName . '.sql.php');
|
||||
|
||||
if(extension_loaded('zlib'))
|
||||
{
|
||||
$result = $this->backup->backFile($this->backupPath . $fileName . '.file.zip.php');
|
||||
if(!$result->result)
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->backup->error->backupFile, $result->error));
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
$this->backup->addFileHeader($this->backupPath . $fileName . '.file.zip.php');
|
||||
}
|
||||
if(extension_loaded('zlib'))
|
||||
{
|
||||
$result = $this->backup->backFile($this->backupPath . $fileName . '.file.zip.php');
|
||||
if(!$result->result)
|
||||
{
|
||||
if($reload == 'yes')
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->backup->error->backupFile, $result->error));
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf($this->lang->backup->error->backupFile, $result->error);
|
||||
}
|
||||
}
|
||||
$this->backup->addFileHeader($this->backupPath . $fileName . '.file.zip.php');
|
||||
}
|
||||
|
||||
echo js::alert($this->lang->backup->success->backup);
|
||||
die(js::reload('parent'));
|
||||
if($reload == 'yes')
|
||||
{
|
||||
echo js::alert($this->lang->backup->success->backup);
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $this->lang->backup->success->backup . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<div id='titlebar'>
|
||||
<div class='heading'><?php echo $lang->backup->common;?></div>
|
||||
<div class='actions'><?php common::printIcon('backup', 'backup', '', '', 'button', 'cloud', 'hiddenwin', 'backup');?></div>
|
||||
<div class='actions'><?php common::printIcon('backup', 'backup', 'reload=yes', '', 'button', 'cloud', 'hiddenwin', 'backup');?></div>
|
||||
</div>
|
||||
|
||||
<div class='panel'>
|
||||
@@ -47,7 +47,7 @@
|
||||
<?php if($i == 0):?>
|
||||
<td <?php if($rowspan > 1) echo "rowspan='$rowspan'"?>>
|
||||
<?php
|
||||
if(common::hasPriv('backup', 'restore')) echo html::a(inlink('restore', "file=$backupFile->name"), $lang->backup->backup, 'hiddenwin', "class='restore'");
|
||||
if(common::hasPriv('backup', 'restore')) echo html::a(inlink('restore', "file=$backupFile->name"), $lang->backup->restore, 'hiddenwin', "class='restore'");
|
||||
if(common::hasPriv('backup', 'delete')) echo html::a(inlink('delete', "file=$backupFile->name"), $lang->delete, 'hiddenwin');
|
||||
?>
|
||||
</td>
|
||||
|
||||
@@ -283,6 +283,7 @@ $lang->admin->menu->custom = array('link' => 'Custom|custom|index', 'subModul
|
||||
$lang->admin->menu->mail = array('link' => 'Email|mail|index', 'subModule' => 'mail');
|
||||
$lang->admin->menu->convert = array('link' => 'Import|convert|index', 'subModule' => 'convert');
|
||||
$lang->admin->menu->backup = array('link' => 'Backup|backup|index', 'subModule' => 'backup');
|
||||
$lang->admin->menu->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->menu->trashes = array('link' => 'Trash|action|trash', 'subModule' => 'action');
|
||||
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
|
||||
|
||||
@@ -294,12 +295,14 @@ $lang->extension = new stdclass();
|
||||
$lang->custom = new stdclass();
|
||||
$lang->editor = new stdclass();
|
||||
$lang->mail = new stdclass();
|
||||
$lang->cron = new stdclass();
|
||||
$lang->dev = new stdclass();
|
||||
|
||||
$lang->convert->menu = $lang->admin->menu;
|
||||
$lang->upgrade->menu = $lang->admin->menu;
|
||||
$lang->action->menu = $lang->admin->menu;
|
||||
$lang->backup->menu = $lang->admin->menu;
|
||||
$lang->cron->menu = $lang->admin->menu;
|
||||
$lang->extension->menu = $lang->admin->menu;
|
||||
$lang->custom->menu = $lang->admin->menu;
|
||||
$lang->editor->menu = $lang->admin->menu;
|
||||
@@ -325,6 +328,7 @@ $lang->menugroup->dept = 'company';
|
||||
$lang->menugroup->todo = 'my';
|
||||
$lang->menugroup->action = 'admin';
|
||||
$lang->menugroup->backup = 'admin';
|
||||
$lang->menugroup->cron = 'admin';
|
||||
$lang->menugroup->extension = 'admin';
|
||||
$lang->menugroup->custom = 'admin';
|
||||
$lang->menugroup->editor = 'admin';
|
||||
|
||||
@@ -112,9 +112,10 @@ $lang->admin->menuOrder[20] = 'editor';
|
||||
$lang->admin->menuOrder[25] = 'mail';
|
||||
$lang->admin->menuOrder[30] = 'custom';
|
||||
$lang->admin->menuOrder[40] = 'convert';
|
||||
$lang->admin->menuOrder[45] = 'backup';
|
||||
$lang->admin->menuOrder[50] = 'dev';
|
||||
$lang->admin->menuOrder[55] = 'trashes';
|
||||
$lang->admin->menuOrder[45] = 'cron';
|
||||
$lang->admin->menuOrder[50] = 'backup';
|
||||
$lang->admin->menuOrder[55] = 'dev';
|
||||
$lang->admin->menuOrder[60] = 'trashes';
|
||||
$lang->convert->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->upgrade->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->action->menuOrder = $lang->admin->menuOrder;
|
||||
@@ -124,4 +125,5 @@ $lang->editor->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->mail->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->custom->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->backup->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->cron->menuOrder = $lang->admin->menuOrder;
|
||||
$lang->dev->menuOrder = $lang->admin->menuOrder;
|
||||
|
||||
@@ -283,6 +283,7 @@ $lang->admin->menu->custom = array('link' => '自定义|custom|index', 'subMo
|
||||
$lang->admin->menu->mail = array('link' => '发信|mail|index', 'subModule' => 'mail');
|
||||
$lang->admin->menu->convert = array('link' => '导入|convert|index', 'subModule' => 'convert');
|
||||
$lang->admin->menu->backup = array('link' => '备份|backup|index', 'subModule' => 'backup');
|
||||
$lang->admin->menu->cron = array('link' => '计划任务|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->menu->trashes = array('link' => '回收站|action|trash', 'subModule' => 'action');
|
||||
$lang->admin->menu->dev = array('link' => '二次开发|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
|
||||
|
||||
@@ -294,12 +295,14 @@ $lang->extension = new stdclass();
|
||||
$lang->custom = new stdclass();
|
||||
$lang->editor = new stdclass();
|
||||
$lang->mail = new stdclass();
|
||||
$lang->cron = new stdclass();
|
||||
$lang->dev = new stdclass();
|
||||
|
||||
$lang->convert->menu = $lang->admin->menu;
|
||||
$lang->upgrade->menu = $lang->admin->menu;
|
||||
$lang->action->menu = $lang->admin->menu;
|
||||
$lang->backup->menu = $lang->admin->menu;
|
||||
$lang->cron->menu = $lang->admin->menu;
|
||||
$lang->extension->menu = $lang->admin->menu;
|
||||
$lang->custom->menu = $lang->admin->menu;
|
||||
$lang->editor->menu = $lang->admin->menu;
|
||||
@@ -325,6 +328,7 @@ $lang->menugroup->dept = 'company';
|
||||
$lang->menugroup->todo = 'my';
|
||||
$lang->menugroup->action = 'admin';
|
||||
$lang->menugroup->backup = 'admin';
|
||||
$lang->menugroup->cron = 'admin';
|
||||
$lang->menugroup->extension = 'admin';
|
||||
$lang->menugroup->custom = 'admin';
|
||||
$lang->menugroup->editor = 'admin';
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<?php endif;?>
|
||||
<?php
|
||||
js::set('onlybody', $onlybody); // set the onlybody var.
|
||||
if($this->loadModel('cron')->runable()) js::execute('startCron()');
|
||||
if(isset($pageJS)) js::execute($pageJS); // load the js for current page.
|
||||
|
||||
/* Load hook files for current page. */
|
||||
|
||||
8
module/cron/config.php
Normal file
8
module/cron/config.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
$config->cron = new stdclass();
|
||||
$config->cron->create = new stdclass();
|
||||
$config->cron->edit = new stdclass();
|
||||
$config->cron->create->requiredFields = 'm,h,dom,mon,dow,command';
|
||||
$config->cron->edit->requiredFields = 'm,h,dom,mon,dow,command';
|
||||
|
||||
$config->cron->maxRunDays = 8;
|
||||
216
module/cron/control.php
Normal file
216
module/cron/control.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* The control file of cron of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package cron
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class cron extends control
|
||||
{
|
||||
/**
|
||||
* Index page.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->view->title = $this->lang->cron->common;
|
||||
$this->view->position[] = $this->lang->cron->common;
|
||||
|
||||
$this->view->crons = $this->cron->getCrons();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turnon cron.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function turnon()
|
||||
{
|
||||
$turnon = $this->config->global->cron ? 0 : 1;
|
||||
$this->loadModel('setting')->setItem('system.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()) die(js::error(dao::getError()));
|
||||
die(js::locate(inlink('index'), 'parent'));
|
||||
}
|
||||
$this->view->title = $this->lang->cron->create . $this->lang->cron->common;
|
||||
$this->view->position[] = html::a(inlink('index'), $this->lang->cron->common);
|
||||
$this->view->position[] = $this->lang->cron->create;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit cron.
|
||||
*
|
||||
* @param int $cronID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($cronID)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$this->cron->update($cronID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
die(js::locate(inlink('index'), 'parent'));
|
||||
}
|
||||
$this->view->title = $this->lang->cron->edit . $this->lang->cron->common;
|
||||
$this->view->position[] = html::a(inlink('index'), $this->lang->cron->common);
|
||||
$this->view->position[] = $this->lang->cron->edit;
|
||||
|
||||
$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);
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cron.
|
||||
*
|
||||
* @param int $cronID
|
||||
* @param string $confirm
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($cronID, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no') die(js::confirm($this->lang->cron->confirmDelete, inlink('delete', "cronID=$cronID&confirm=yes")));
|
||||
|
||||
$this->dao->delete()->from(TABLE_CRON)->where('id')->eq($cronID)->exec();
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(!$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)
|
||||
{
|
||||
/* When cron is null then die. */
|
||||
if(empty($crons)) die();
|
||||
if(empty($parsedCrons)) die();
|
||||
|
||||
/* Run crons. */
|
||||
$now = new datetime('now');
|
||||
foreach($parsedCrons as $id => $cron)
|
||||
{
|
||||
/* Skip stop and running cron.*/
|
||||
$cronInfo = $this->cron->getById($id);
|
||||
if(empty($cronInfo) or $cronInfo->status == 'stop' or $cronInfo->status == 'running') continue;
|
||||
|
||||
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 == 'zentao')
|
||||
{
|
||||
parse_str($cron['command'], $params);
|
||||
if(isset($params['moduleName']) and isset($params['methodName']))
|
||||
{
|
||||
$output = $this->fetch($params['moduleName'], $params['methodName']);
|
||||
}
|
||||
}
|
||||
elseif(isset($crons[$id]) and $crons[$id]->type == 'system')
|
||||
{
|
||||
exec($cron['command'], $output, $return);
|
||||
if($output) $output = join("\n", $output);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save log. */
|
||||
if($output and $this->config->debug)
|
||||
{
|
||||
$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);
|
||||
}
|
||||
}
|
||||
47
module/cron/lang/en.php
Normal file
47
module/cron/lang/en.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
$lang->cron->common = 'Cron';
|
||||
$lang->cron->index = 'Index';
|
||||
$lang->cron->list = 'List';
|
||||
$lang->cron->create = 'Create';
|
||||
$lang->cron->edit = 'Edit';
|
||||
$lang->cron->delete = 'Delete';
|
||||
$lang->cron->toggle = 'Activation/Disable';
|
||||
$lang->cron->turnon = 'Open/Close';
|
||||
|
||||
$lang->cron->m = 'Minute';
|
||||
$lang->cron->h = 'Hour';
|
||||
$lang->cron->dom = 'Day';
|
||||
$lang->cron->mon = 'Month';
|
||||
$lang->cron->dow = 'Week';
|
||||
$lang->cron->command = 'Command';
|
||||
$lang->cron->status = 'Status';
|
||||
$lang->cron->type = 'Type';
|
||||
$lang->cron->remark = 'Remark';
|
||||
$lang->cron->lastTime = 'Last run time';
|
||||
|
||||
$lang->cron->turnonList['1'] = 'Open';
|
||||
$lang->cron->turnonList['0'] = 'Close';
|
||||
|
||||
$lang->cron->statusList['normal'] = 'Normal';
|
||||
$lang->cron->statusList['running'] = 'Running';
|
||||
$lang->cron->statusList['stop'] = 'Stop';
|
||||
|
||||
$lang->cron->typeList['zentao'] = 'Self call';
|
||||
$lang->cron->typeList['system'] = 'System command';
|
||||
|
||||
$lang->cron->toggleList['start'] = 'Activation';
|
||||
$lang->cron->toggleList['stop'] = 'Disable';
|
||||
|
||||
$lang->cron->confirmDelete = 'Do you want to delete the task?';
|
||||
$lang->cron->introduction = <<<EOD
|
||||
<p>Timing tasks such as compute burn , backup. Absolve themselves of layout timing task.</p>
|
||||
<p>This function has yet to be perfect, so the function is turned off by default</p>
|
||||
<p>Whether to open the function? <a href="%s" target='hiddenwin'>Open timing task</a></p>
|
||||
EOD;
|
||||
|
||||
$lang->cron->notice = new stdclass();
|
||||
$lang->cron->notice->m = 'Range : 0-59,"*" express the range of numbers, "/" express "Every", "-" express digital range.';
|
||||
$lang->cron->notice->h = 'Range : 0-23';
|
||||
$lang->cron->notice->dom = 'Range : 1-31';
|
||||
$lang->cron->notice->mon = 'Range : 1-12';
|
||||
$lang->cron->notice->dow = 'Range : 0-6';
|
||||
47
module/cron/lang/zh-cn.php
Normal file
47
module/cron/lang/zh-cn.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
$lang->cron->common = '定时任务';
|
||||
$lang->cron->index = '首页';
|
||||
$lang->cron->list = '任务列表';
|
||||
$lang->cron->create = '添加';
|
||||
$lang->cron->edit = '编辑';
|
||||
$lang->cron->delete = '删除';
|
||||
$lang->cron->toggle = '激活/禁用';
|
||||
$lang->cron->turnon = '打开/关闭';
|
||||
|
||||
$lang->cron->m = '分';
|
||||
$lang->cron->h = '小时';
|
||||
$lang->cron->dom = '天';
|
||||
$lang->cron->mon = '月';
|
||||
$lang->cron->dow = '周';
|
||||
$lang->cron->command = '命令';
|
||||
$lang->cron->status = '状态';
|
||||
$lang->cron->type = '任务类型';
|
||||
$lang->cron->remark = '备注';
|
||||
$lang->cron->lastTime = '最后执行';
|
||||
|
||||
$lang->cron->turnonList['1'] = '打开';
|
||||
$lang->cron->turnonList['0'] = '关闭';
|
||||
|
||||
$lang->cron->statusList['normal'] = '正常';
|
||||
$lang->cron->statusList['running'] = '运行中';
|
||||
$lang->cron->statusList['stop'] = '停止';
|
||||
|
||||
$lang->cron->typeList['zentao'] = '禅道自调用';
|
||||
$lang->cron->typeList['system'] = '操作系统命令';
|
||||
|
||||
$lang->cron->toggleList['start'] = '激活';
|
||||
$lang->cron->toggleList['stop'] = '禁用';
|
||||
|
||||
$lang->cron->confirmDelete = '是否删除该计划任务?';
|
||||
$lang->cron->introduction = <<<EOD
|
||||
<p>计划任务功能可以定时执行诸如更新燃尽图、备份等操作,免除自己布置定时任务。</p>
|
||||
<p>该功能还有待完善,所以默认关闭该功能</p>
|
||||
<p>是否开启该功能?<a href="%s" target='hiddenwin'>打开计划任务</a></p>
|
||||
EOD;
|
||||
|
||||
$lang->cron->notice = new stdclass();
|
||||
$lang->cron->notice->m = '取值范围:0-59,"*"代表取值范围内的数字,"/"代表"每", "-"代表数字范围。';
|
||||
$lang->cron->notice->h = '取值范围:0-23';
|
||||
$lang->cron->notice->dom = '取值范围:1-31';
|
||||
$lang->cron->notice->mon = '取值范围:1-12';
|
||||
$lang->cron->notice->dow = '取值范围:0-6';
|
||||
228
module/cron/model.php
Normal file
228
module/cron/model.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of cron module of ZenTaoCMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package cron
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class cronModel extends model
|
||||
{
|
||||
/**
|
||||
* Get by Id.
|
||||
*
|
||||
* @param int $cronID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getById($cronID)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_CRON)->where('id')->eq($cronID)->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get crons.
|
||||
*
|
||||
* @param string $params
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getCrons($params = '')
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_CRON)
|
||||
->where('1=1')
|
||||
->beginIF(strpos($params, 'nostop') !== false)->andWhere('status')->ne('stop')->fi()
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse crons.
|
||||
*
|
||||
* @param array $crons
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function parseCron($crons)
|
||||
{
|
||||
$this->app->loadClass('crontab', true);
|
||||
|
||||
$parsedCron = array();
|
||||
foreach($crons as $cron)
|
||||
{
|
||||
$row = "{$cron->m} {$cron->h} {$cron->dom} {$cron->mon} {$cron->dow} {$cron->command}";
|
||||
preg_match_all('/(\S+\s+){5}|.*/', $row, $matchs);
|
||||
if($matchs[0])
|
||||
{
|
||||
try
|
||||
{
|
||||
$parsedCron = array();
|
||||
$parsedCron['schema'] = trim($matchs[0][0]);
|
||||
$parsedCron['command'] = trim($matchs[0][1]);
|
||||
$parsedCron['cron'] = CronExpression::factory($parsedCron['schema']);
|
||||
$parsedCron['time'] = $parsedCron['cron']->getNextRunDate();
|
||||
$parsedCrons[$cron->id] = $parsedCron;
|
||||
}
|
||||
catch(InvalidArgumentException $e)
|
||||
{
|
||||
$this->dao->update(TABLE_CRON)->set('status')->eq('stop')->where('id')->eq($cron->id)->exec();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->dao->update(TABLE_CRON)->set('lastTime')->eq(date(DT_DATETIME1))->where('lastTime')->eq('0000-00-00 00:00:00')->andWhere('status')->ne('stop')->exec();
|
||||
return $parsedCrons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change cron status.
|
||||
*
|
||||
* @param int $cronID
|
||||
* @param string $status
|
||||
* @param bool $changeTime
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function changeStatus($cronID, $status, $changeTime = false)
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->status = $status;
|
||||
if($status == 'running' or $changeTime) $data->lastTime = date(DT_DATETIME1);
|
||||
$this->dao->update(TABLE_CRON)->data($data)->where('id')->eq($cronID)->exec();
|
||||
return dao::isError() ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log cron.
|
||||
*
|
||||
* @param string $log
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function logCron($log)
|
||||
{
|
||||
if(!is_writable($this->app->getLogRoot())) return false;
|
||||
|
||||
$file = $this->app->getLogRoot() . 'cron.' . date('Ymd') . '.log.php';
|
||||
if(!is_file($file)) $log = "<?php\n die();\n" . $log;
|
||||
|
||||
$fp = fopen($file, "a");
|
||||
fwrite($fp, $log);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last execed time.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLastTime()
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_CRON)->orderBy('lastTime desc')->limit(1)->fetch('lastTime');
|
||||
}
|
||||
|
||||
/**
|
||||
* Runable cron.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function runable()
|
||||
{
|
||||
if(!$this->config->global->cron) return false;
|
||||
|
||||
$lastTime = $this->getLastTime();
|
||||
if($lastTime == '0000-00-00 00:00:00' or ((time() - strtotime($lastTime)) / 3600 > 1)) return true;
|
||||
if(!isset($this->config->cron->run->status)) return true;
|
||||
if($this->config->cron->run->status == 'stop') return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check change cron.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkChange()
|
||||
{
|
||||
$updatedCron = $this->dao->select('*')->from(TABLE_CRON)->where('lastTime')->eq('0000-00-00 00:00:00')->andWhere('status')->ne('stop')->fetch();
|
||||
return $updatedCron ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create cron.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$cron = fixer::input('post')
|
||||
->add('type', 'custom')
|
||||
->add('status', 'normal')
|
||||
->add('lastTime', '0000-00-00 00:00:00')
|
||||
->skipSpecial('m,h,dom,mon,dow,command')
|
||||
->get();
|
||||
$this->dao->insert(TABLE_CRON)->data($cron)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->cron->create->requiredFields, 'notempty')
|
||||
->exec();
|
||||
|
||||
return $this->dao->lastInsertID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cron.
|
||||
*
|
||||
* @param int $cronID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function update($cronID)
|
||||
{
|
||||
$cron = fixer::input('post')
|
||||
->add('lastTime', '0000-00-00 00:00:00')
|
||||
->skipSpecial('m,h,dom,mon,dow,command')
|
||||
->get();
|
||||
$this->dao->update(TABLE_CRON)->data($cron)
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->cron->create->requiredFields, 'notempty')
|
||||
->where('id')->eq($cronID)->exec();
|
||||
return dao::isError() ? false : true;
|
||||
}
|
||||
|
||||
public function markCronStatus($status, $configID = 0)
|
||||
{
|
||||
if($configID)
|
||||
{
|
||||
$this->dao->update(TABLE_CONFIG)->set('value')->eq($status)->where('id')->eq($configID)->exec();
|
||||
return $configID;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->owner = 'system';
|
||||
$data->module = 'cron';
|
||||
$data->section = 'run';
|
||||
$data->key = 'status';
|
||||
$data->value = $status;
|
||||
$this->dao->insert(TABLE_CONFIG)->data($data)->exec();
|
||||
return $this->dao->lastInsertID();
|
||||
}
|
||||
}
|
||||
|
||||
public function getConfigID()
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_CONFIG)
|
||||
->where('owner')->eq('system')
|
||||
->andWhere('module')->eq('cron')
|
||||
->andWhere('section')->eq('run')
|
||||
->andWhere('`key`')->eq('status')
|
||||
->fetch('id');
|
||||
}
|
||||
}
|
||||
68
module/cron/view/create.html.php
Normal file
68
module/cron/view/create.html.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* The index view file of cron module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package cron
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div class='container mw-700px'>
|
||||
<div id='titlebar'>
|
||||
<div class='heading'>
|
||||
<strong><?php echo $lang->cron->common?></strong>
|
||||
<small class'text-muted'> <?php echo $lang->cron->create?></small>
|
||||
</div>
|
||||
</div>
|
||||
<form class='form-condensed' method='post' id='dataform' target='hiddenwin'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='rowhead w-80px'><?php echo $lang->cron->m;?></th>
|
||||
<td class='w-p20'><?php echo html::input('m', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->m;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->h;?></th>
|
||||
<td><?php echo html::input('h', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->h;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dom;?></th>
|
||||
<td><?php echo html::input('dom', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dom;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->mon;?></th>
|
||||
<td><?php echo html::input('mon', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->mon;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dow;?></th>
|
||||
<td><?php echo html::input('dow', '', "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dow;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->command;?></th>
|
||||
<td colspan='2'><?php echo html::input('command', '', "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->remark;?></th>
|
||||
<td colspan='2'><?php echo html::input('remark', '', "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->type;?></th>
|
||||
<td><?php echo html::select('type', $lang->cron->typeList, 'system', "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><?php echo html::submitButton()?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
68
module/cron/view/edit.html.php
Normal file
68
module/cron/view/edit.html.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view file of cron module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package cron
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div class='container mw-700px'>
|
||||
<div id='titlebar'>
|
||||
<div class='heading'>
|
||||
<strong><?php echo $lang->cron->common?></strong>
|
||||
<small class'text-muted'> <?php echo $lang->cron->edit?></small>
|
||||
</div>
|
||||
</div>
|
||||
<form class='form-condensed' method='post' id='dataform' target='hiddenwin'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='rowhead w-80px'><?php echo $lang->cron->m;?></th>
|
||||
<td class='w-p20'><?php echo html::input('m', $cron->m, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->m;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->h;?></th>
|
||||
<td><?php echo html::input('h', $cron->h, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->h;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dom;?></th>
|
||||
<td><?php echo html::input('dom', $cron->dom, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dom;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->mon;?></th>
|
||||
<td><?php echo html::input('mon', $cron->mon, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->mon;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->dow;?></th>
|
||||
<td><?php echo html::input('dow', $cron->dow, "class='form-control'")?></td>
|
||||
<td><?php echo $lang->cron->notice->dow;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->command;?></th>
|
||||
<td colspan='2'><?php echo html::input('command', str_replace("'", "'", $cron->command), "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->remark;?></th>
|
||||
<td colspan='2'><?php echo html::input('remark', $cron->remark, "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->cron->type;?></th>
|
||||
<td><?php echo html::select('type', $lang->cron->typeList, $cron->type, "class='form-control'")?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><?php echo html::submitButton()?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
70
module/cron/view/index.html.php
Normal file
70
module/cron/view/index.html.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* The index view file of cron module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package cron
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='titlebar'>
|
||||
<div class='heading'><?php echo $lang->cron->common;?></div>
|
||||
<div class='actions'><?php if(common::hasPriv('cron', 'turnon') and $config->global->cron) echo html::a(inlink('turnon'), $lang->cron->turnonList[0] . $lang->cron->common, 'hiddenwin', "class='btn'");?></div>
|
||||
</div>
|
||||
|
||||
<?php if($config->global->cron):?>
|
||||
<div class='panel'>
|
||||
<div class='panel-heading'>
|
||||
<strong><?php echo $lang->cron->list?></strong>
|
||||
<div class='panel-actions pull-right'><?php echo html::a(inlink('create'), $lang->cron->create, '', "class='btn btn-primary btn-sm'")?></div>
|
||||
</div>
|
||||
<table class='table table-condensed table-bordered active-disabled table-fixed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-60px'><?php echo $lang->cron->m?></th>
|
||||
<th class='w-60px'><?php echo $lang->cron->h?></th>
|
||||
<th class='w-60px'><?php echo $lang->cron->dom?></th>
|
||||
<th class='w-60px'><?php echo $lang->cron->mon?></th>
|
||||
<th class='w-60px'><?php echo $lang->cron->dow?></th>
|
||||
<th><?php echo $lang->cron->command?></th>
|
||||
<th class='w-100px'><?php echo $lang->cron->remark?></th>
|
||||
<th class='w-120px'><?php echo $lang->cron->lastTime?></th>
|
||||
<th class='w-60px'><?php echo $lang->cron->status?></th>
|
||||
<th class='w-100px'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class='text-center'>
|
||||
<?php foreach($crons as $cron):?>
|
||||
<tr>
|
||||
<td><?php echo $cron->m;?></td>
|
||||
<td><?php echo $cron->h;?></td>
|
||||
<td><?php echo $cron->dom;?></td>
|
||||
<td><?php echo $cron->mon;?></td>
|
||||
<td><?php echo $cron->dow;?></td>
|
||||
<td class='text-left' title='<?php echo $cron->command?>'><?php echo $cron->command;?></td>
|
||||
<td class='text-left' title='<?php echo $cron->remark?>'><?php echo $cron->remark;?></td>
|
||||
<td><?php echo substr($cron->lastTime, 2);?></td>
|
||||
<td><?php echo zget($lang->cron->statusList, $cron->status);?></td>
|
||||
<td class='text-left'>
|
||||
<?php
|
||||
if(common::hasPriv('cron', 'toggle') and !empty($cron->command)) echo html::a(inlink('toggle', "id=$cron->id&status=" . ($cron->status == 'stop' ? 'normal' : 'stop')), $cron->status == 'stop' ? $lang->cron->toggleList['start'] : $lang->cron->toggleList['stop'], 'hiddenwin');
|
||||
if($cron->buildin == 0 and common::hasPriv('cron', 'edit')) echo html::a(inlink('edit', "id=$cron->id"), $lang->edit);
|
||||
if($cron->buildin == 0 and common::hasPriv('cron', 'delete')) echo html::a(inlink('delete', "id=$cron->id"), $lang->delete, 'hiddenwin');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='container mw-700px'>
|
||||
<div class='panel-body'><?php printf($lang->cron->introduction, inlink('turnon'))?></div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
<<<<<<< HEAD
|
||||
$lang->dev->common = 'Develop';
|
||||
$lang->dev->api = 'API';
|
||||
$lang->dev->db = 'Database';
|
||||
@@ -79,3 +80,18 @@ $lang->dev->tableList['svn'] = 'SVN';
|
||||
$lang->dev->tableList['testcase'] = 'Testcase';
|
||||
$lang->dev->tableList['tree'] = 'Tree';
|
||||
$lang->dev->tableList['upgrade'] = 'Upgrade';
|
||||
=======
|
||||
$lang->dev->common = 'Dev';
|
||||
$lang->dev->api = 'API';
|
||||
$lang->dev->db = 'Database';
|
||||
$lang->dev->editor = 'Editor';
|
||||
$lang->dev->dbList = 'Datebases';
|
||||
|
||||
$lang->dev->fields = array();
|
||||
$lang->dev->fields['id'] = 'ID';
|
||||
$lang->dev->fields['name'] = 'Field';
|
||||
$lang->dev->fields['desc'] = 'Desc';
|
||||
$lang->dev->fields['type'] = 'Type';
|
||||
$lang->dev->fields['length'] = 'Length';
|
||||
$lang->dev->fields['null'] = 'Empty';
|
||||
>>>>>>> fdc283afd74c3cf379fd24153ece79fe519c0b20
|
||||
|
||||
@@ -424,8 +424,19 @@ class extension extends control
|
||||
{
|
||||
$tmpName = $_FILES['file']['tmp_name'];
|
||||
$fileName = $_FILES['file']['name'];
|
||||
$extension = basename($fileName, '.zip');
|
||||
move_uploaded_file($tmpName, $this->app->getTmpRoot() . "/extension/$fileName");
|
||||
$extension = basename($fileName, '.zip');
|
||||
$return = $this->extension->extractPackage($extension);
|
||||
if($return->result != 'ok') die(js::alert(sprintf($this->lang->extension->errorExtracted, $packageFile, $return->error)));
|
||||
|
||||
$info = $this->extension->parseExtensionCFG($extension);
|
||||
if(isset($info->code) and $info->code != $extension)
|
||||
{
|
||||
$classFile = $this->app->loadClass('zfile');
|
||||
$classFile->removeDir("ext/$extension");
|
||||
$extension = $info->code;
|
||||
}
|
||||
|
||||
$info = $this->extension->getInfoFromDB($extension);
|
||||
$type = $info->status == 'installed' ? 'upgrade' : 'install';
|
||||
$link = $type == 'install' ? inlink('install', "extension=$extension") : inlink('upgrade', "extension=$extension");
|
||||
|
||||
@@ -82,6 +82,8 @@ class gitModel extends model
|
||||
public function run()
|
||||
{
|
||||
$this->setRepos();
|
||||
if(empty($this->repos)) return false;
|
||||
|
||||
$this->setLogRoot();
|
||||
$this->setRestartFile();
|
||||
|
||||
@@ -90,11 +92,13 @@ class gitModel extends model
|
||||
$this->printLog("begin repo $name");
|
||||
$repo = (object)$repo;
|
||||
$repo->name = $name;
|
||||
$this->setRepo($repo);
|
||||
if(!$this->setRepo($repo)) return false;
|
||||
|
||||
$savedRevision = $this->getSavedRevision();
|
||||
$this->printLog("start from revision $savedRevision");
|
||||
$logs = $this->getRepoLogs($repo, $savedRevision);
|
||||
if(empty($logs)) return false;
|
||||
|
||||
$this->printLog("get " . count($logs) . " logs");
|
||||
if(empty($logs)) continue;
|
||||
|
||||
@@ -171,12 +175,18 @@ class gitModel extends model
|
||||
* Set the repos.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setRepos()
|
||||
{
|
||||
if(!$this->config->git->repos) die("You must set one git repo.\n");
|
||||
if(!$this->config->git->repos)
|
||||
{
|
||||
echo "You must set one git repo.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->repos = $this->config->git->repos;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,13 +194,16 @@ class gitModel extends model
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setRepo($repo)
|
||||
{
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
|
||||
$this->setLogFile($repo->name);
|
||||
$this->setRepoRoot($repo);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,12 +211,18 @@ class gitModel extends model
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setClient($repo)
|
||||
{
|
||||
if($this->config->git->client == '') die("You must set the git client file.\n");
|
||||
if($this->config->git->client == '')
|
||||
{
|
||||
echo "You must set the git client file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->client = $this->config->git->client;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,7 +272,11 @@ class gitModel extends model
|
||||
}
|
||||
exec($cmd, $list, $return);
|
||||
|
||||
if(!$list and $return) die("Some error occers: \nThe command is $cmd\n");
|
||||
if(!$list and $return)
|
||||
{
|
||||
echo "Some error occers: \nThe command is $cmd\n";
|
||||
return false;
|
||||
}
|
||||
if(!$list and !$return) return array();
|
||||
|
||||
/* Process logs. */
|
||||
@@ -375,6 +398,7 @@ class gitModel extends model
|
||||
if(!$repo) return false;
|
||||
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
putenv('LC_CTYPE=en_US.UTF-8');
|
||||
|
||||
$path = str_replace('%2F', '/', urlencode($path));
|
||||
@@ -399,6 +423,7 @@ class gitModel extends model
|
||||
if(!$repo) return false;
|
||||
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
|
||||
putenv('LC_CTYPE=en_US.UTF-8');
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ $lang->moduleOrder[155] = 'api';
|
||||
$lang->moduleOrder[160] = 'file';
|
||||
$lang->moduleOrder[165] = 'misc';
|
||||
$lang->moduleOrder[170] = 'backup';
|
||||
$lang->moduleOrder[175] = 'cron';
|
||||
$lang->moduleOrder[180] = 'dev';
|
||||
|
||||
$lang->resource = new stdclass();
|
||||
|
||||
@@ -535,6 +537,9 @@ $lang->resource->mail->edit = 'edit';
|
||||
$lang->resource->mail->save = 'save';
|
||||
$lang->resource->mail->test = 'test';
|
||||
$lang->resource->mail->reset = 'reset';
|
||||
$lang->resource->mail->browse = 'browse';
|
||||
$lang->resource->mail->delete = 'delete';
|
||||
$lang->resource->mail->batchDelete = 'batchDelete';
|
||||
|
||||
$lang->mail->methodOrder[5] = 'index';
|
||||
$lang->mail->methodOrder[10] = 'detect';
|
||||
@@ -542,6 +547,9 @@ $lang->mail->methodOrder[15] = 'edit';
|
||||
$lang->mail->methodOrder[20] = 'save';
|
||||
$lang->mail->methodOrder[25] = 'test';
|
||||
$lang->mail->methodOrder[30] = 'reset';
|
||||
$lang->mail->methodOrder[35] = 'browse';
|
||||
$lang->mail->methodOrder[40] = 'delete';
|
||||
$lang->mail->methodOrder[45] = 'batchDelete';
|
||||
|
||||
/* custom. */
|
||||
$lang->resource->custom = new stdclass();
|
||||
@@ -825,6 +833,28 @@ $lang->backup->methodOrder[10] = 'backup';
|
||||
$lang->backup->methodOrder[15] = 'restore';
|
||||
$lang->backup->methodOrder[20] = 'delete';
|
||||
|
||||
$lang->resource->cron = new stdclass();
|
||||
$lang->resource->cron->index = 'index';
|
||||
$lang->resource->cron->turnon = 'turnon';
|
||||
$lang->resource->cron->create = 'create';
|
||||
$lang->resource->cron->edit = 'edit';
|
||||
$lang->resource->cron->toggle = 'toggle';
|
||||
$lang->resource->cron->delete = 'delete';
|
||||
|
||||
$lang->cron->methodOrder[5] = 'index';
|
||||
$lang->cron->methodOrder[10] = 'turnon';
|
||||
$lang->cron->methodOrder[15] = 'create';
|
||||
$lang->cron->methodOrder[20] = 'edit';
|
||||
$lang->cron->methodOrder[25] = 'toggle';
|
||||
$lang->cron->methodOrder[30] = 'delete';
|
||||
|
||||
$lang->resource->dev = new stdclass();
|
||||
$lang->resource->dev->api = 'api';
|
||||
$lang->resource->dev->db = 'db';
|
||||
|
||||
$lang->dev->methodOrder[5] = 'api';
|
||||
$lang->dev->methodOrder[10] = 'db';
|
||||
|
||||
/* Every version of new privilege. */
|
||||
$lang->changelog['1.0.1'][] = 'project-computeBurn';
|
||||
|
||||
@@ -1015,3 +1045,13 @@ $lang->changelog['6.4'][] = 'release-linkBug';
|
||||
$lang->changelog['6.4'][] = 'release-unlinkBug';
|
||||
$lang->changelog['6.4'][] = 'release-batchUnlinkBug';
|
||||
$lang->changelog['6.4'][] = 'story-batchAssignTo';
|
||||
|
||||
$lang->changelog['7.1'][] = 'cron-index';
|
||||
$lang->changelog['7.1'][] = 'cron-turnon';
|
||||
$lang->changelog['7.1'][] = 'cron-create';
|
||||
$lang->changelog['7.1'][] = 'cron-edit';
|
||||
$lang->changelog['7.1'][] = 'cron-toggle';
|
||||
$lang->changelog['7.1'][] = 'cron-delete';
|
||||
$lang->changelog['7.1'][] = 'mail-browse';
|
||||
$lang->changelog['7.1'][] = 'mail-delete';
|
||||
$lang->changelog['7.1'][] = 'mail-batchDelete';
|
||||
|
||||
@@ -17,9 +17,9 @@ class mail extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct();
|
||||
parent::__construct($moduleName, $methodName);
|
||||
|
||||
/* Task #1967. check the function of fsocket. */
|
||||
if(!function_exists('fsockopen'))
|
||||
@@ -121,6 +121,7 @@ class mail extends control
|
||||
|
||||
$mailConfig->turnon = $this->post->turnon;
|
||||
$mailConfig->mta = 'smtp';
|
||||
$mailConfig->async = $this->post->async;
|
||||
$mailConfig->fromAddress = trim($this->post->fromAddress);
|
||||
$mailConfig->fromName = trim($this->post->fromName);
|
||||
$mailConfig->smtp->host = trim($this->post->host);
|
||||
@@ -218,4 +219,100 @@ class mail extends control
|
||||
$this->dao->delete('*')->from(TABLE_CONFIG)->where('module')->eq('mail')->exec();
|
||||
$this->locate(inlink('detect'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Async send mail.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function asyncSend()
|
||||
{
|
||||
$queueList = $this->mail->getQueue('wait', 'id_asc');
|
||||
$now = helper::now();
|
||||
if(isset($this->config->mail->async))$this->config->mail->async = 0;
|
||||
foreach($queueList as $queue)
|
||||
{
|
||||
$this->mail->send($queue->toList, $queue->subject, $queue->body, $queue->ccList);
|
||||
|
||||
$data = new stdclass();
|
||||
$data->sendTime = $now;
|
||||
$data->status = 'send';
|
||||
if($this->mail->isError())
|
||||
{
|
||||
$data->status = 'fail';
|
||||
$data->failReason = join("\n", $this->mail->getError());
|
||||
}
|
||||
$this->dao->update(TABLE_MAILQUEUE)->data($data)->where('id')->eq($queue->id)->exec();
|
||||
|
||||
$log = "Send #$query->id result is $data->status\n";
|
||||
if($data->status == 'fail') $log .= "reason is $data->failReason\n";
|
||||
echo $log;
|
||||
}
|
||||
echo "OK\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse mail queue.
|
||||
*
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
{
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$this->view->title = $this->lang->mail->browse;
|
||||
$this->view->position[] = html::a(inlink('edit'), $this->lang->mail->common);
|
||||
$this->view->position[] = $this->lang->mail->browse;
|
||||
|
||||
$this->view->queueList = $this->mail->getQueue(null, $orderBy, $pager);
|
||||
$this->view->pager = $pager;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete mail queue.
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $confirm
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no') die(js::confirm($this->lang->mail->confirmDelete, inlink('delete', "id=$id&confirm=yes")));
|
||||
|
||||
$this->dao->delete()->from(TABLE_MAILQUEUE)->where('id')->eq($id)->exec();
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch delete mail queue.
|
||||
*
|
||||
* @param string $confirm
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchDelete($confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no')
|
||||
{
|
||||
if(empty($_POST)) die(js::reload('parent'));
|
||||
$idList = join('|', $this->post->mailIDList);
|
||||
die(js::confirm($this->lang->mail->confirmDelete, inlink('batchDelete', "confirm=yes") . ($this->config->requestType == 'GET' ? '&' : '?') . "idList=$idList"));
|
||||
}
|
||||
$idList = array();
|
||||
if(isset($_GET['idList'])) $idList = explode(',', $_GET['idList']);
|
||||
|
||||
if($idList) $this->dao->delete()->from(TABLE_MAILQUEUE)->where('id')->in($idList)->exec();
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@ $lang->mail->edit = 'Configure';
|
||||
$lang->mail->save = 'Successfully saved';
|
||||
$lang->mail->test = 'Testing';
|
||||
$lang->mail->reset = 'Reset';
|
||||
$lang->mail->browse = 'Mail list';
|
||||
$lang->mail->delete = 'Delete mail';
|
||||
$lang->mail->batchDelete = 'Batch delete';
|
||||
|
||||
$lang->mail->turnon = 'Turnon';
|
||||
$lang->mail->async = 'Asynchronous';
|
||||
$lang->mail->fromAddress = 'From email';
|
||||
$lang->mail->fromName = 'From title';
|
||||
$lang->mail->mta = 'MTA';
|
||||
@@ -20,9 +24,24 @@ $lang->mail->secure = 'Secure';
|
||||
$lang->mail->debug = 'Debug';
|
||||
$lang->mail->charset = 'Charset';
|
||||
|
||||
$lang->mail->toList = 'Addressee';
|
||||
$lang->mail->subjectName = 'Subject';
|
||||
$lang->mail->addedBy = 'Sender';
|
||||
$lang->mail->addedDate = 'Added date';
|
||||
$lang->mail->sendTime = 'Send time';
|
||||
$lang->mail->status = 'Status';
|
||||
$lang->mail->ccList = 'Copy to';
|
||||
$lang->mail->failReason = 'Fail Reason';
|
||||
|
||||
$lang->mail->statusList['send'] = 'Success';
|
||||
$lang->mail->statusList['fail'] = 'Fail';
|
||||
|
||||
$lang->mail->turnonList[1] = 'on';
|
||||
$lang->mail->turnonList[0] = 'off';
|
||||
|
||||
$lang->mail->asyncList[1] = 'Yes';
|
||||
$lang->mail->asyncList[0] = 'No';
|
||||
|
||||
$lang->mail->debugList[0] = 'off';
|
||||
$lang->mail->debugList[1] = 'normal';
|
||||
$lang->mail->debugList[2] = 'high';
|
||||
@@ -40,8 +59,8 @@ $lang->mail->successSaved = 'The configuration has been successfully saved.';
|
||||
$lang->mail->subject = "It's a testing email from zentao.";
|
||||
$lang->mail->content = 'If you can see this, the email notification feature can work now!';
|
||||
$lang->mail->successSended = 'Successfully sended!';
|
||||
$lang->mail->confirmDelete = 'Confirm delete mail?';
|
||||
$lang->mail->sendmailTips = 'Tips: system will not send mail to current user.';
|
||||
$lang->mail->needConfigure = "I can not find the configuration, please configure it first.";
|
||||
$lang->mail->nofsocket = 'The fsocket correlation function is disabled, not letter! Please enlarge the setting of allow_url_fopen to On in php.ini and open the extension of openssl. Restart apache.';
|
||||
$lang->mail->noOpenssl = 'Please open the extension of openssl when use tls. Restart apache.';
|
||||
$lang->mail->noCurl = 'Please open the extension of curl when use tls and ssl. Restart apache.';
|
||||
|
||||
@@ -6,8 +6,12 @@ $lang->mail->edit = '编辑配置';
|
||||
$lang->mail->save = '成功保存';
|
||||
$lang->mail->test = '测试发信';
|
||||
$lang->mail->reset = '重置';
|
||||
$lang->mail->browse = '邮件列表';
|
||||
$lang->mail->delete = '删除邮件';
|
||||
$lang->mail->batchDelete = '批量删除';
|
||||
|
||||
$lang->mail->turnon = '是否打开';
|
||||
$lang->mail->async = '异步发送';
|
||||
$lang->mail->fromAddress = '发信邮箱';
|
||||
$lang->mail->fromName = '发信人';
|
||||
$lang->mail->mta = '发信方式';
|
||||
@@ -20,9 +24,24 @@ $lang->mail->secure = '是否加密';
|
||||
$lang->mail->debug = '调试级别';
|
||||
$lang->mail->charset = '编码';
|
||||
|
||||
$lang->mail->toList = '收信人';
|
||||
$lang->mail->subjectName = '主题';
|
||||
$lang->mail->addedBy = '发送者';
|
||||
$lang->mail->addedDate = '创建时间';
|
||||
$lang->mail->sendTime = '发送时间';
|
||||
$lang->mail->status = '状态';
|
||||
$lang->mail->ccList = '抄送给';
|
||||
$lang->mail->failReason = '失败原因';
|
||||
|
||||
$lang->mail->statusList['send'] = '成功';
|
||||
$lang->mail->statusList['fail'] = '失败';
|
||||
|
||||
$lang->mail->turnonList[1] = '打开';
|
||||
$lang->mail->turnonList[0] = '关闭';
|
||||
|
||||
$lang->mail->asyncList[1] = '是';
|
||||
$lang->mail->asyncList[0] = '否';
|
||||
|
||||
$lang->mail->debugList[0] = '关闭';
|
||||
$lang->mail->debugList[1] = '一般';
|
||||
$lang->mail->debugList[2] = '较高';
|
||||
@@ -40,6 +59,7 @@ $lang->mail->successSaved = '配置信息已经成功保存。';
|
||||
$lang->mail->subject = '测试邮件';
|
||||
$lang->mail->content = '邮箱设置成功';
|
||||
$lang->mail->successSended = '成功发送!';
|
||||
$lang->mail->confirmDelete = '是否删除邮件?';
|
||||
$lang->mail->sendmailTips = '提示:系统不会为当前操作者发信。';
|
||||
$lang->mail->needConfigure = '无法找到邮件配置信息,请先配置邮件发送参数。';
|
||||
$lang->mail->nofsocket = 'fsocket相关函数被禁用,不能发信!请在php.ini中修改allow_url_fopen为On,打开openssl扩展。 保存并重新启动apache。';
|
||||
|
||||
@@ -242,6 +242,7 @@ class mailModel extends model
|
||||
public function send($toList, $subject, $body = '', $ccList = '', $includeMe = false)
|
||||
{
|
||||
if(!$this->config->mail->turnon) return;
|
||||
if(isset($this->config->mail->async) and $this->config->mail->async) return $this->addQueue($toList, $subject, $body, $ccList, $includeMe);
|
||||
|
||||
ob_start();
|
||||
$toList = $toList ? explode(',', str_replace(' ', '', $toList)) : array();
|
||||
@@ -436,4 +437,58 @@ class mailModel extends model
|
||||
$this->errors = array();
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add queue.
|
||||
*
|
||||
* @param string $toList
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param string $ccList
|
||||
* @param bool $includeMe
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function addQueue($toList, $subject, $body = '', $ccList = '', $includeMe = false)
|
||||
{
|
||||
$toList = $toList ? explode(',', str_replace(' ', '', $toList)) : array();
|
||||
$ccList = $ccList ? explode(',', str_replace(' ', '', $ccList)) : array();
|
||||
|
||||
/* Process toList and ccList, remove current user from them. If toList is empty, use the first cc as to. */
|
||||
if($includeMe == false)
|
||||
{
|
||||
$account = isset($this->app->user->account) ? $this->app->user->account : '';
|
||||
|
||||
foreach($toList as $key => $to) if(trim($to) == $account or !trim($to)) unset($toList[$key]);
|
||||
foreach($ccList as $key => $cc) if(trim($cc) == $account or !trim($cc)) unset($ccList[$key]);
|
||||
}
|
||||
$toList = join(',', $toList);
|
||||
$ccList = join(',', $ccList);
|
||||
|
||||
$data = new stdclass();
|
||||
$data->toList = $toList;
|
||||
$data->ccList = $ccList;
|
||||
$data->subject = $subject;
|
||||
$data->body = $body;
|
||||
$data->addedBy = $this->app->user->account;
|
||||
$data->addedDate = helper::now();
|
||||
$this->dao->insert(TABLE_MAILQUEUE)->data($data)->autocheck()->batchCheck('toList,subject', 'notempty')->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get queue.
|
||||
*
|
||||
* @param string $status
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getQueue($status = '', $orderBy = 'id_desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_MAILQUEUE)
|
||||
->where('1=1')
|
||||
->beginIF($status)->andWhere('status')->eq($status)->fi()
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
}
|
||||
}
|
||||
|
||||
70
module/mail/view/browse.html.php
Normal file
70
module/mail/view/browse.html.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* The browse view file of mail module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package mail
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='titlebar'>
|
||||
<div class='heading'><?php echo $lang->mail->browse?></div>
|
||||
</div>
|
||||
<form method='post' action='<?php echo inlink('batchDelete')?>' target='hiddenwin'>
|
||||
<div class='panel'>
|
||||
<table class='table table-condensed table-bordered active-disabled table-fixed tablesorter'>
|
||||
<?php $vars = "orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
|
||||
<th class='w-80px'> <?php common::printOrderLink('toList', $orderBy, $vars, $lang->mail->toList);?></th>
|
||||
<th class='w-150px'> <?php common::printOrderLink('subject', $orderBy, $vars, $lang->mail->subjectName);?></th>
|
||||
<th class='w-80px'> <?php common::printOrderLink('addedBy', $orderBy, $vars, $lang->mail->addedBy);?></th>
|
||||
<th class='w-150px'> <?php common::printOrderLink('addedDate', $orderBy, $vars, $lang->mail->addedDate);?></th>
|
||||
<th class='w-150px'> <?php common::printOrderLink('sendTime', $orderBy, $vars, $lang->mail->sendTime);?></th>
|
||||
<th class='w-60px'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->mail->status);?></th>
|
||||
<th> <?php echo $lang->mail->failReason;?></th>
|
||||
<th class='w-80px'> <?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class='text-center'>
|
||||
<?php foreach($queueList as $queue):?>
|
||||
<tr>
|
||||
<td>
|
||||
<input type='checkbox' name='mailIDList[]' value='<?php echo $queue->id;?>'/>
|
||||
<?php echo $queue->id?>
|
||||
</td>
|
||||
<td><?php echo zget($users, $queue->toList, $queue->toList)?></td>
|
||||
<td class='text-left'><?php echo $queue->subject?></td>
|
||||
<td><?php echo zget($users, $queue->addedBy, $queue->addedBy)?></td>
|
||||
<td><?php echo $queue->addedDate?></td>
|
||||
<td><?php echo $queue->sendTime?></td>
|
||||
<td><?php echo zget($lang->mail->statusList, $queue->status)?></td>
|
||||
<td class='text-left'><?php echo $queue->failReason?></td>
|
||||
<td><?php if(common::hasPriv('mail', 'delete')) echo html::a(inlink('delete', "id=$queue->id"), $lang->delete, 'hiddenwin');?></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='9'>
|
||||
<?php
|
||||
if(count($queueList))
|
||||
{
|
||||
echo "<div class='btn-group'>" . html::selectButton() . '</div>';
|
||||
if(common::hasPriv('mail', 'batchDelete')) echo html::submitButton($lang->delete);
|
||||
}
|
||||
$pager->show();
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -25,6 +25,12 @@ include '../../common/view/header.html.php';
|
||||
<th class='rowhead w-120px'><?php echo $lang->mail->turnon; ?></th>
|
||||
<td><?php echo html::radio('turnon', $lang->mail->turnonList, 1);?></td>
|
||||
</tr>
|
||||
<?php if($config->global->cron):?>
|
||||
<tr>
|
||||
<th class='text-top'><?php echo $lang->mail->async?></th>
|
||||
<td><?php echo html::radio('async', $lang->mail->asyncList, zget($config->mail, 'async', 0))?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->mail->fromAddress; ?></th>
|
||||
<td><?php echo html::input('fromAddress', $mailConfig->fromAddress, "class='form-control'");?></td>
|
||||
@@ -72,6 +78,7 @@ include '../../common/view/header.html.php';
|
||||
echo html::submitButton();
|
||||
if($this->config->mail->turnon and $mailExist) echo html::linkButton($lang->mail->test, inlink('test'));
|
||||
echo html::linkButton($lang->mail->reset, inlink('reset'));
|
||||
if(common::hasPriv('mail', 'browse') and isset($config->mail->async) and $config->mail->async and $config->global->cron) echo html::linkButton($lang->mail->browse, inlink('browse'));
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* The html template file of index method of index module of ZenTaoPMS.
|
||||
*
|
||||
<?php
|
||||
/**
|
||||
* The html template file of index method of index module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package ZenTaoPMS
|
||||
* @version $Id: index.html.php 1947 2011-06-29 11:58:03Z wwccss $
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/sparkline.html.php';?>
|
||||
<?php css::import($defaultTheme . 'index.css', $config->version);?>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<?php include './blockprojects.html.php';?>
|
||||
<?php include './blockproducts.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<?php if(common::hasPriv('company', 'dynamic')) include './blockdynamic.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktodoes.html.php';?>
|
||||
</div>
|
||||
<?php if($app->user->role and strpos('qa|qd', $app->user->role) !== false):?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktasks.html.php';?>
|
||||
</div>
|
||||
<?php elseif($app->user->role and strpos('po|pd', $app->user->role) !== false):?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockstories.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktasks.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package ZenTaoPMS
|
||||
* @version $Id: index.html.php 1947 2011-06-29 11:58:03Z wwccss $
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/sparkline.html.php';?>
|
||||
<?php css::import($defaultTheme . 'index.css', $config->version);?>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<?php include './blockprojects.html.php';?>
|
||||
<?php include './blockproducts.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<?php if(common::hasPriv('company', 'dynamic')) include './blockdynamic.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktodoes.html.php';?>
|
||||
</div>
|
||||
<?php if($app->user->role and strpos('qa|qd', $app->user->role) !== false):?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktasks.html.php';?>
|
||||
</div>
|
||||
<?php elseif($app->user->role and strpos('po|pd', $app->user->role) !== false):?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockstories.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blocktasks.html.php';?>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-6">
|
||||
<?php include './blockbugs.html.php';?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -18,9 +18,9 @@ class project extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct();
|
||||
parent::__construct($moduleName, $methodName);
|
||||
if($this->methodName != 'computeburn')
|
||||
{
|
||||
$this->projects = $this->project->getPairs('nocode');
|
||||
@@ -789,7 +789,7 @@ class project extends control
|
||||
{
|
||||
$this->view->burns = $this->project->computeBurn();
|
||||
if($reload == 'yes') die(js::reload('parent'));
|
||||
die($this->display());
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
$headerHooks = glob(dirname(dirname(__FILE__)) . "/ext/view/featurebar.*.html.hook.php");
|
||||
if(!empty($headerHooks))
|
||||
{
|
||||
foreach($headerHooks as $fileName) helper::import($fileName);
|
||||
foreach($headerHooks as $fileName) include($fileName);
|
||||
}
|
||||
?>
|
||||
|
||||
0
module/report/ext/control/.gitkeep
Normal file → Executable file
0
module/report/ext/control/.gitkeep
Normal file → Executable file
0
module/report/ext/lang/zh-cn/.gitkeep
Normal file → Executable file
0
module/report/ext/lang/zh-cn/.gitkeep
Normal file → Executable file
0
module/report/ext/model/.gitkeep
Normal file → Executable file
0
module/report/ext/model/.gitkeep
Normal file → Executable file
0
module/report/ext/view/.gitkeep
Normal file → Executable file
0
module/report/ext/view/.gitkeep
Normal file → Executable file
@@ -82,6 +82,8 @@ class svnModel extends model
|
||||
public function run()
|
||||
{
|
||||
$this->setRepos();
|
||||
if(empty($this->repos)) return false;
|
||||
|
||||
$this->setLogRoot();
|
||||
$this->setRestartFile();
|
||||
|
||||
@@ -90,11 +92,13 @@ class svnModel extends model
|
||||
$this->printLog("begin repo $name");
|
||||
$repo = (object)$repo;
|
||||
$repo->name = $name;
|
||||
$this->setRepo($repo);
|
||||
if(!$this->setRepo($repo)) return false;
|
||||
|
||||
$savedRevision = $this->getSavedRevision();
|
||||
$this->printLog("start from revision $savedRevision");
|
||||
$logs = $this->getRepoLogs($repo, $savedRevision);
|
||||
if(empty($logs)) return false;
|
||||
|
||||
$this->printLog("get " . count($logs) . " logs");
|
||||
|
||||
$this->printLog('begin parsing logs');
|
||||
@@ -169,12 +173,18 @@ class svnModel extends model
|
||||
* Set the repos.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setRepos()
|
||||
{
|
||||
if(!$this->config->svn->repos) die("You must set one svn repo.\n");
|
||||
if(!$this->config->svn->repos)
|
||||
{
|
||||
echo "You must set one svn repo.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->repos = $this->config->svn->repos;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,13 +192,16 @@ class svnModel extends model
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setRepo($repo)
|
||||
{
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
|
||||
$this->setLogFile($repo->name);
|
||||
$this->setRepoRoot($repo);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,11 +209,16 @@ class svnModel extends model
|
||||
*
|
||||
* @param object $repo
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function setClient($repo)
|
||||
{
|
||||
if($this->config->svn->client == '') die("You must set the svn client file.\n");
|
||||
if($this->config->svn->client == '')
|
||||
{
|
||||
echo "You must set the svn client file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->client = $this->config->svn->client . " --non-interactive";
|
||||
if(stripos($repo->path, 'https') === 0 or stripos($repo->path, 'svn') === 0)
|
||||
{
|
||||
@@ -212,6 +230,7 @@ class svnModel extends model
|
||||
}
|
||||
}
|
||||
if(isset($repo->username)) $this->client .= " --username $repo->username --password $repo->password --no-auth-cache";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,7 +277,11 @@ class svnModel extends model
|
||||
$cmd = $this->client . " log -r $fromRevision:HEAD -v --xml $repo->path";
|
||||
$rawLogs = `$cmd`;
|
||||
$logs = @simplexml_load_string($rawLogs); // Convert it to object.
|
||||
if(!$logs) die("Some error occers: \nThe command is $cmd\n the svn logs is $rawLogs\n");
|
||||
if(!$logs)
|
||||
{
|
||||
echo "Some error occers: \nThe command is $cmd\n the svn logs is $rawLogs\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Process logs. */
|
||||
foreach($logs->logentry as $entry) $parsedLogs[] = $this->convertLog($entry);
|
||||
@@ -367,6 +390,7 @@ class svnModel extends model
|
||||
if(!$repo) return false;
|
||||
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
putenv('LC_CTYPE=en_US.UTF-8');
|
||||
|
||||
$oldRevision = $revision - 1;
|
||||
@@ -393,6 +417,7 @@ class svnModel extends model
|
||||
if(!$repo) return false;
|
||||
|
||||
$this->setClient($repo);
|
||||
if(empty($this->client)) return false;
|
||||
|
||||
putenv('LC_CTYPE=en_US.UTF-8');
|
||||
|
||||
|
||||
@@ -1100,6 +1100,7 @@ class task extends control
|
||||
/* Set related files. */
|
||||
if(isset($relatedFiles[$task->id]))
|
||||
{
|
||||
$task->files = '';
|
||||
foreach($relatedFiles[$task->id] as $file)
|
||||
{
|
||||
$fileURL = 'http://' . $this->server->http_host . $this->config->webRoot . "data/upload/{$this->app->company->id}/" . $file->pathname;
|
||||
|
||||
@@ -60,6 +60,6 @@
|
||||
$headerHooks = glob(dirname(dirname(__FILE__)) . "/ext/view/featurebar.*.html.hook.php");
|
||||
if(!empty($headerHooks))
|
||||
{
|
||||
foreach($headerHooks as $fileName) helper::import($fileName);
|
||||
foreach($headerHooks as $fileName) include($fileName);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
$headerHooks = glob(dirname(dirname(__FILE__)) . "/ext/view/featurebar.*.html.hook.php");
|
||||
if(!empty($headerHooks))
|
||||
{
|
||||
foreach($headerHooks as $fileName) helper::import($fileName);
|
||||
foreach($headerHooks as $fileName) include($fileName);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1178,6 +1178,15 @@ function fixStyle()
|
||||
if($actions.length) $('#titlebar > .heading').css('padding-right', $actions.width());
|
||||
}
|
||||
|
||||
function startCron()
|
||||
{
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
timeout: 100,
|
||||
url: createLink('cron', 'ajaxExec')
|
||||
});
|
||||
}
|
||||
|
||||
/* Ping the server every some minutes to keep the session. */
|
||||
needPing = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user