Merge branch 'master' of https://github.com/easysoft/zentaopms
This commit is contained in:
@@ -46,12 +46,14 @@ pms:
|
||||
mkdir -p buildxx/framework
|
||||
mkdir -p buildxx/db
|
||||
mkdir -p buildxx/www
|
||||
mkdir -p buildxx/module/common/ext/model/
|
||||
svn export https://github.com/easysoft/xuanxuan.git/branches/master/ranzhi/
|
||||
cp ranzhi/config/ext/xuanxuan.php buildxx/config/ext/
|
||||
cp -r ranzhi/lib/phpaes buildxx/lib/
|
||||
cp -r ranzhi/framework/xuanxuan.class.php buildxx/framework/
|
||||
cp -r ranzhi/db/xuanxuan.sql buildxx/db/
|
||||
cp -r ranzhi/app/sys/chat buildxx/module/
|
||||
cp -r ranzhi/app/sys/common/ext/model/hook buildxx/module/common/ext/model/
|
||||
cp -r ranzhi/app/sys/action buildxx/module/
|
||||
cp -r xuanxuan/module/* buildxx/module/
|
||||
cp -r xuanxuan/www/* buildxx/www/
|
||||
|
||||
+2
-1
@@ -29,7 +29,7 @@ $config->moduleVar = 'm'; // 请求类型为GET:模块变量
|
||||
$config->methodVar = 'f'; // 请求类型为GET:模块变量名。 requestType=GET: the method var name.
|
||||
$config->viewVar = 't'; // 请求类型为GET:视图变量名。 requestType=GET: the view var name.
|
||||
$config->sessionVar = 'zentaosid'; // 请求类型为GET:session变量名。 requestType=GET: the session var name.
|
||||
$config->views = ',html,json,mhtml,'; // 支持的视图类型。 Supported view formats.
|
||||
$config->views = ',html,json,mhtml,xhtml,'; // 支持的视图类型。 Supported view formats.
|
||||
|
||||
/* 支持的主题和语言。Supported thems and languages. */
|
||||
$config->themes['default'] = 'default';
|
||||
@@ -39,6 +39,7 @@ $config->langs['en'] = 'English';
|
||||
|
||||
/* 设备类型视图文件前缀。The prefix for view file for different device. */
|
||||
$config->devicePrefix['mhtml'] = '';
|
||||
$config->devicePrefix['xhtml'] = 'x.';
|
||||
|
||||
/* 默认值设置。Default settings. */
|
||||
$config->default = new stdclass();
|
||||
|
||||
@@ -20,4 +20,121 @@
|
||||
include dirname(__FILE__) . '/base/control.class.php';
|
||||
class control extends baseControl
|
||||
{
|
||||
/**
|
||||
* 设置视图文件:主视图文件,扩展视图文件, 站点扩展视图文件,以及钩子脚本。
|
||||
* Set view files: the main file, extension view file, site extension view file and hook files.
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
* @param string $methodName method name
|
||||
* @access public
|
||||
* @return string the view file
|
||||
*/
|
||||
public function setViewFile($moduleName, $methodName)
|
||||
{
|
||||
$moduleName = strtolower(trim($moduleName));
|
||||
$methodName = strtolower(trim($methodName));
|
||||
|
||||
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
|
||||
$viewExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'view');
|
||||
|
||||
$viewType = ($this->viewType == 'mhtml' or $this->viewType == 'xhtml') ? 'html' : $this->viewType;
|
||||
$mainViewFile = $modulePath . 'view' . DS . $this->devicePrefix . $methodName . '.' . $viewType . '.php';
|
||||
|
||||
/* If the main view file doesn't exist, set the device prefix to empty and reset the main view file. */
|
||||
if($this->viewType == 'mhtml' or $this->viewType == 'xhtml')
|
||||
{
|
||||
if(!file_exists($mainViewFile))
|
||||
{
|
||||
if($this->viewType == 'xhtml') $this->app->viewType = 'html';
|
||||
$this->devicePrefix = '';
|
||||
$mainViewFile = $modulePath . 'view' . DS . $this->devicePrefix . $methodName . '.' . $viewType . '.php';
|
||||
}
|
||||
}
|
||||
|
||||
$viewFile = $mainViewFile;
|
||||
|
||||
if(!empty($viewExtPath))
|
||||
{
|
||||
$commonExtViewFile = $viewExtPath['common'] . $this->devicePrefix . $methodName . ".{$viewType}.php";
|
||||
$siteExtViewFile = empty($viewExtPath['site']) ? '' : $viewExtPath['site'] . $this->devicePrefix . $methodName . ".{$viewType}.php";
|
||||
|
||||
$viewFile = file_exists($commonExtViewFile) ? $commonExtViewFile : $mainViewFile;
|
||||
$viewFile = (!empty($siteExtViewFile) and file_exists($siteExtViewFile)) ? $siteExtViewFile : $viewFile;
|
||||
if(!is_file($viewFile)) $this->app->triggerError("the view file $viewFile not found", __FILE__, __LINE__, $exit = true);
|
||||
|
||||
$commonExtHookFiles = glob($viewExtPath['common'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php");
|
||||
$siteExtHookFiles = empty($viewExtPath['site']) ? '' : glob($viewExtPath['site'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php");
|
||||
$extHookFiles = array_merge((array) $commonExtHookFiles, (array) $siteExtHookFiles);
|
||||
}
|
||||
|
||||
if(!empty($extHookFiles)) return array('viewFile' => $viewFile, 'hookFiles' => $extHookFiles);
|
||||
return $viewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认渲染方法,适用于viewType = html的时候。
|
||||
* Default parse method when viewType != json, like html.
|
||||
*
|
||||
* @param string $moduleName module name
|
||||
* @param string $methodName method name
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function parseDefault($moduleName, $methodName)
|
||||
{
|
||||
/**
|
||||
* 设置视图文件。(PHP7有一个bug,不能直接$viewFile = $this->setViewFile())。
|
||||
* Set viewFile. (Can't assign $viewFile = $this->setViewFile() directly because one php7's bug.)
|
||||
*/
|
||||
$results = $this->setViewFile($moduleName, $methodName);
|
||||
$viewFile = $results;
|
||||
if(is_array($results)) extract($results);
|
||||
|
||||
/**
|
||||
* 获得当前页面的CSS和JS。
|
||||
* Get css and js codes for current method.
|
||||
*/
|
||||
$css = $this->getCSS($moduleName, $methodName);
|
||||
$js = $this->getJS($moduleName, $methodName);
|
||||
/* If the js or css file doesn't exist, set the device prefix to empty and reset the js or css file. */
|
||||
if($this->viewType == 'xhtml')
|
||||
{
|
||||
if(!$css)
|
||||
{
|
||||
$this->devicePrefix = '';
|
||||
$css = $this->getCSS($moduleName, $methodName);
|
||||
}
|
||||
if(!$js)
|
||||
{
|
||||
$this->devicePrefix = '';
|
||||
$js = $this->getJS($moduleName, $methodName);
|
||||
}
|
||||
}
|
||||
if($css) $this->view->pageCSS = $css;
|
||||
if($js) $this->view->pageJS = $js;
|
||||
|
||||
/**
|
||||
* 切换到视图文件所在的目录,以保证视图文件里面的include语句能够正常运行。
|
||||
* Change the dir to the view file to keep the relative pathes work.
|
||||
*/
|
||||
$currentPWD = getcwd();
|
||||
chdir(dirname($viewFile));
|
||||
|
||||
/**
|
||||
* 使用extract安定ob方法渲染$viewFile里面的代码。
|
||||
* Use extract and ob functions to eval the codes in $viewFile.
|
||||
*/
|
||||
extract((array)$this->view);
|
||||
ob_start();
|
||||
include $viewFile;
|
||||
if(isset($hookFiles)) foreach($hookFiles as $hookFile) if(file_exists($hookFile)) include $hookFile;
|
||||
$this->output .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
/**
|
||||
* 渲染完毕后,再切换回之前的路径。
|
||||
* At the end, chang the dir to the previous.
|
||||
*/
|
||||
chdir($currentPWD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,4 +156,38 @@ class router extends baseRouter
|
||||
$this->session->set('rand', $this->session->random);
|
||||
echo json_encode($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* PATH_INFO方式解析,获取$URI和$viewType。
|
||||
* Parse PATH_INFO, get the $URI and $viewType.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function parsePathInfo()
|
||||
{
|
||||
parent::parsePathInfo();
|
||||
|
||||
if($this->get->display == 'card')
|
||||
{
|
||||
$this->viewType = 'xhtml';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求方式解析,获取$URI和$viewType。
|
||||
* Parse GET, get $URI and $viewType.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function parseGET()
|
||||
{
|
||||
parent::parseGET();
|
||||
|
||||
if($this->get->display == 'card')
|
||||
{
|
||||
$this->viewType = 'xhtml';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ class commonModel extends model
|
||||
public static function printClientLink()
|
||||
{
|
||||
global $lang;
|
||||
echo html::a(helper::createLink('misc', 'downloadClient', '', '', true), "<i class='icon-bell'></i>", '', "title='$lang->downloadClient' class='text-primary iframe' data-width='400'") . ' ';
|
||||
echo html::a(helper::createLink('misc', 'downloadClient', '', '', true), "<i class='icon-bell'></i>", '', "title='$lang->downloadClient' class='text-primary iframe' data-width='600'") . ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ $(function()
|
||||
if(data)
|
||||
{
|
||||
if(typeof data == 'string') data = $.parseJSON(data);
|
||||
if(typeof data.message == 'string') notifyMessage(data.message);
|
||||
if(typeof data.message == 'string') notifyMessage(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ var browseType = '<?php echo $browseType;?>';
|
||||
<li><?php common::printLink('doc', 'deleteLib', "libID=$libID", "<i class='icon icon-close'></i>" . $lang->delete, 'hiddenwin');?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php common::printLink('doc', 'create', "libID=$libID", "<i class='icon icon-plus'></i> " . $this->lang->doc->create, '', "class='btn btn-primary'");?>
|
||||
<?php common::printLink('doc', 'create', "libID=$libID&moduleID=$moduleID", "<i class='icon icon-plus'></i> " . $this->lang->doc->create, '', "class='btn btn-primary'");?>
|
||||
<?php endif;?>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@ var browseType = '<?php echo $browseType;?>';
|
||||
<span class="text-muted"><?php echo $lang->doc->noDoc;?></span>
|
||||
<?php if(common::hasPriv('doc', 'create')):?>
|
||||
<span class="text-muted"><?php echo $lang->youCould;?></span>
|
||||
<?php echo html::a($this->createLink('doc', 'create', "libID={$libID}"), "<i class='icon icon-plus'></i> " . $lang->doc->create, '', "class='btn btn-info'");?>
|
||||
<?php echo html::a($this->createLink('doc', 'create', "libID={$libID}&moduleID=$moduleID"), "<i class='icon icon-plus'></i> " . $lang->doc->create, '', "class='btn btn-info'");?>
|
||||
<?php endif;?>
|
||||
<?php elseif($browseType == 'byediteddate'):?>
|
||||
<span class="text-muted"><?php echo $lang->doc->noEditedDoc;?></span>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<li><?php common::printLink('doc', 'deleteLib', "libID=$libID", "<i class='icon icon-close'></i>" . $lang->delete, 'hiddenwin');?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php common::printLink('doc', 'create', "libID=$libID", "<i class='icon icon-plus'></i> " . $this->lang->doc->create, '', "class='btn btn-primary'");?>
|
||||
<?php common::printLink('doc', 'create', "libID=$libID&moduleID=$moduleID", "<i class='icon icon-plus'></i> " . $this->lang->doc->create, '', "class='btn btn-primary'");?>
|
||||
<?php endif;?>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@
|
||||
<span class="text-muted"><?php echo $lang->doc->noDoc;?></span>
|
||||
<?php if(common::hasPriv('doc', 'create')):?>
|
||||
<span class="text-muted"><?php echo $lang->youCould;?></span>
|
||||
<?php echo html::a($this->createLink('doc', 'create', "libID={$libID}"), "<i class='icon icon-plus'></i> " . $lang->doc->create, '', "class='btn btn-info'");?>
|
||||
<?php echo html::a($this->createLink('doc', 'create', "libID={$libID}&moduleID=$moduleID"), "<i class='icon icon-plus'></i> " . $lang->doc->create, '', "class='btn btn-info'");?>
|
||||
<?php endif;?>
|
||||
<?php elseif($browseType == 'byediteddate'):?>
|
||||
<span class="text-muted"><?php echo $lang->doc->noEditedDoc;?></span>
|
||||
|
||||
@@ -92,12 +92,12 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan='2' class='text-center'>
|
||||
<td colspan='4' class='text-center'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php
|
||||
echo html::submitButton();
|
||||
if($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 !empty($config->mail->async) and !empty($config->global->cron)) echo html::linkButton($lang->mail->browse, inlink('browse'));
|
||||
if($config->mail->turnon and $mailExist) echo html::a(inlink('test'), $lang->mail->test, '', "class='btn btn-wide'");
|
||||
echo html::a(inlink('reset'), $lang->mail->reset, '', "class='btn btn-wide'");
|
||||
if(common::hasPriv('mail', 'browse') and !empty($config->mail->async) and !empty($config->global->cron)) echo html::a(inlink('browse'), $lang->mail->browse, '', "class='btn btn-wide'");
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -86,11 +86,13 @@ class message extends control
|
||||
$this->dao->update(TABLE_NOTIFY)->set('status')->eq('sended')->set('sendTime')->eq(helper::now())->where('id')->in($idList)->exec();
|
||||
|
||||
foreach($todos as $todo) $messages .= $todo->data . $newline;
|
||||
if($windowBlur) $messages = strip_tags($messages);
|
||||
|
||||
if($windowBlur)
|
||||
{
|
||||
echo json_encode(array('message' => $messages));
|
||||
preg_match_all("/<a href='([^\']+)'/", $messages, $out);
|
||||
$link = count($out[1]) ? $out[1][0] : '';
|
||||
$messages = strip_tags($messages);
|
||||
echo json_encode(array('message' => $messages, 'url' => $link));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+196
-52
@@ -88,109 +88,253 @@ class misc extends control
|
||||
* Download zentao client.
|
||||
*
|
||||
* @access public
|
||||
* @param string $action
|
||||
* @param string $os
|
||||
* @param string $version
|
||||
* @return void
|
||||
*/
|
||||
public function downloadClient($os = '', $confirm = 'no', $send = 'no')
|
||||
public function downloadClient($action = 'check', $os = '', $version = '')
|
||||
{
|
||||
if($_POST) die(js::locate($this->createLink('misc', 'downloadClient', "os={$this->post->os}&confirm=yes"), 'parent'));
|
||||
|
||||
if($send == 'yes')
|
||||
if($_POST)
|
||||
{
|
||||
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/tmp/';
|
||||
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
|
||||
$version = $this->post->version;
|
||||
$os = $this->post->os;
|
||||
|
||||
/* write login info into config file. */
|
||||
$defaultUser = new stdclass();
|
||||
$defaultUser->server = common::getSysURL();
|
||||
$defaultUser->account = $this->app->user->account;
|
||||
die(js::locate($this->createLink('misc', 'downloadClient', "action=getPackage&os=$os"), 'parent'));
|
||||
}
|
||||
|
||||
$loginInfo = new stdclass();
|
||||
$loginInfo->ui = $defaultUser;
|
||||
$loginInfo = json_encode($loginInfo);
|
||||
if($action == 'check')
|
||||
{
|
||||
$error = false;
|
||||
$errorInfo = '';
|
||||
|
||||
$loginFile = $clientDir . 'config.json';
|
||||
file_put_contents($loginFile, $loginInfo);
|
||||
$cacheDir = $this->app->getBasePath() . 'tmp/cache/';
|
||||
if(!is_dir($cacheDir))
|
||||
{
|
||||
$result = mkdir($cacheDir, 0755, true);
|
||||
if($result == false)
|
||||
{
|
||||
$error = true;
|
||||
$errorInfo = sprintf($this->lang->misc->client->errorInfo->dirNotExist, $cacheDir, $cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_writable($cacheDir))
|
||||
{
|
||||
$error = true;
|
||||
$errorInfo = sprintf($this->lang->misc->client->errorInfo->dirNotWritable, $cacheDir, $cacheDir);
|
||||
}
|
||||
|
||||
$this->view->error = $error;
|
||||
$this->view->errorInfo = $errorInfo;
|
||||
|
||||
if(!$error) die(js::locate($this->createLink('misc', 'downloadClient', "action=selectPackage")));
|
||||
}
|
||||
|
||||
if($action == 'selectPackage')
|
||||
{
|
||||
$os = 'windows64';
|
||||
$agentOS = helper::getOS();
|
||||
if(strpos($agentOS, 'Windows') !== false) $os = 'windows64';
|
||||
if(strpos($agentOS, 'Linux') !== false) $os = 'linux64';
|
||||
if(strpos($agentOS, 'Mac') !== false) $os = 'mac';
|
||||
|
||||
$this->view->os = $os;
|
||||
}
|
||||
|
||||
if($action == 'getPackage')
|
||||
{
|
||||
$this->view->os = $os;
|
||||
$this->view->account = $this->app->user->account;
|
||||
}
|
||||
|
||||
if($action == 'clearTmpPackage')
|
||||
{
|
||||
$account = $this->app->user->account;
|
||||
$tmpDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
|
||||
|
||||
if(is_dir($tmpDir))
|
||||
{
|
||||
$zfile = $this->app->loadClass('zfile');
|
||||
$zfile->removeDir($tmpDir);
|
||||
}
|
||||
|
||||
die(js::closeModal('parent.parent', 'this'));
|
||||
}
|
||||
|
||||
if($action == 'downloadPackage')
|
||||
{
|
||||
$account = $this->app->user->account;
|
||||
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
|
||||
|
||||
define('PCLZIP_TEMPORARY_DIR', $clientDir);
|
||||
$this->app->loadClass('pclzip', true);
|
||||
$clientFile = $clientDir . 'zentaoClient.zip';
|
||||
$archive = new pclzip($clientFile);
|
||||
|
||||
if($os == 'mac')
|
||||
$zipContent = file_get_contents($clientFile);
|
||||
if(is_dir($clientDir))
|
||||
{
|
||||
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'xuanxuan.app/Contents/Resouces');
|
||||
$zfile = $this->app->loadClass('zfile');
|
||||
$zfile->removeDir($clientDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'resources/build-in');
|
||||
}
|
||||
|
||||
if($result == 0) die("Error : " . $archive->errorInfo(true));
|
||||
|
||||
unlink($clientDir);
|
||||
|
||||
$this->fetch('file', 'sendDownHeader', array('fileName' => 'client.zip', 'zip', $zipContent));
|
||||
}
|
||||
|
||||
$this->view->os = $os;
|
||||
$this->view->confirm = $confirm;
|
||||
$this->view->action = $action;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function ajaxGetClient($os)
|
||||
/**
|
||||
* Ajax get client package.
|
||||
*
|
||||
* @param string $os
|
||||
* @param string $version
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetClientPackage($os = '', $version = '')
|
||||
{
|
||||
set_time_limit (0);
|
||||
session_write_close();
|
||||
|
||||
$response = array();
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
|
||||
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/';
|
||||
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
|
||||
|
||||
$account = $this->app->user->account;
|
||||
$tmpDir = $clientDir . "/$account/";
|
||||
if(!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);
|
||||
|
||||
if($os == 'windows64') $clientName = "xuanxuan.win64.zip";
|
||||
if($os == 'windows32') $clientName = "xuanxuan.win32.zip";
|
||||
if($os == 'linux64') $clientName = "xuanxuan.linux.x64.zip";
|
||||
if($os == 'linux32') $clientName = "xuanxuan.linux.ia32.zip";
|
||||
if($os == 'mac') $clientName = "xuanxuan.mac.zip";
|
||||
|
||||
$tmpDir = $clientDir . '/tmp/';
|
||||
if(!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);
|
||||
|
||||
$needCache = false;
|
||||
$packageFile = $clientDir . $clientName;
|
||||
if(!file_exists($packageFile))
|
||||
{
|
||||
$handle = "http://dl.pts.com/xuanxuan/xuanxuan.win64.zip";
|
||||
$url = "http://dl.pts.com/xuanxuan/";
|
||||
$xxFile = $url . $clientName;
|
||||
$needCache = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$handle = $packageFile;
|
||||
$xxFile = $packageFile;
|
||||
}
|
||||
|
||||
$client = $tmpDir . 'zentaoClient.zip';
|
||||
|
||||
$clientHd = fopen($handle, "rb");
|
||||
if($clientHd)
|
||||
$clientFile = $tmpDir . 'zentaoClient.zip';
|
||||
if($xxHd = fopen($xxFile, "rb"))
|
||||
{
|
||||
$newf = fopen($client, "wb");
|
||||
if($newf)
|
||||
if($clientHd = fopen($clientFile, "wb"))
|
||||
{
|
||||
while(!feof($clientHd))
|
||||
while(!feof($xxHd))
|
||||
{
|
||||
fwrite($newf, fread($clientHd, 1024 * 8 ), 1024 * 8 );
|
||||
$result = fwrite($clientHd, fread($xxHd, 1024 * 8 ), 1024 * 8 );
|
||||
if($result == false)
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
|
||||
$this->send($response);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
|
||||
$this->send($response);
|
||||
}
|
||||
fclose($xxHd);
|
||||
fclose($clientHd);
|
||||
}
|
||||
else
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
if ($clientHd) fclose($clientHd);
|
||||
if ($newf) fclose($newf);
|
||||
|
||||
$response = array();
|
||||
$response['result'] = 'success';
|
||||
if($needCache) file_put_contents($packageFile, file_get_contents($clientFile));
|
||||
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
public function ajaxGetDownProgress($os = '')
|
||||
/**
|
||||
* Ajax set client config to client package.
|
||||
*
|
||||
* @param string $os
|
||||
* @param string $version
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxSetClientConfig($os = '', $version = '')
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
|
||||
$account = $this->app->user->account;
|
||||
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
|
||||
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
|
||||
|
||||
/* write login info into config file. */
|
||||
$defaultUser = new stdclass();
|
||||
$defaultUser->server = common::getSysURL();
|
||||
$defaultUser->account = $this->app->user->account;
|
||||
|
||||
$loginInfo = new stdclass();
|
||||
$loginInfo->ui = $defaultUser;
|
||||
$loginInfo = json_encode($loginInfo);
|
||||
|
||||
$loginFile = $clientDir . 'config.json';
|
||||
file_put_contents($loginFile, $loginInfo);
|
||||
|
||||
define('PCLZIP_TEMPORARY_DIR', $clientDir);
|
||||
$this->app->loadClass('pclzip', true);
|
||||
$clientFile = $clientDir . 'zentaoClient.zip';
|
||||
$archive = new pclzip($clientFile);
|
||||
|
||||
if($os == 'mac')
|
||||
{
|
||||
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'xuanxuan.app/Contents/Resouces');
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'resources/build-in');
|
||||
}
|
||||
|
||||
if($result == 0)
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = $archive->errorInfo(true);
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get client package size.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetPackageSize()
|
||||
{
|
||||
$account = $this->app->user->account;
|
||||
$packageFile = $this->app->getBasePath() . 'tmp/cache/client/' . $account . '/zentaoClient.zip';
|
||||
|
||||
$size = 0;
|
||||
if(file_exists($packageFile))
|
||||
{
|
||||
$size = filesize($packageFile);
|
||||
$size = $size ? round($size / 1048576, 2) : 0;
|
||||
}
|
||||
|
||||
$response = array();
|
||||
$response['result'] = 'unfinished';
|
||||
$response['result'] = 'success';
|
||||
$response['size'] = $size;
|
||||
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
+15
-1
@@ -16,7 +16,12 @@ $lang->misc->api = 'https://api.zentao.net';
|
||||
$lang->misc->enApi = 'http://api.zentao.pm';
|
||||
|
||||
$lang->misc->client = new stdclass();
|
||||
$lang->misc->client->download = 'Download';
|
||||
$lang->misc->client->version = 'Select Version';
|
||||
$lang->misc->client->os = 'Select OS';
|
||||
$lang->misc->client->download = 'Download';
|
||||
$lang->misc->client->downloading = 'Downloading:';
|
||||
$lang->misc->client->downloaded = 'Downloaded successful!';
|
||||
$lang->misc->client->setConfig = 'Set config successful!';
|
||||
|
||||
$lang->misc->client->osList['windows64'] = 'Windows 64';
|
||||
$lang->misc->client->osList['windows32'] = 'Windows 32';
|
||||
@@ -24,6 +29,15 @@ $lang->misc->client->osList['linux64'] = 'Linux 64';
|
||||
$lang->misc->client->osList['linux32'] = 'Linux 32';
|
||||
$lang->misc->client->osList['mac'] = 'Mac';
|
||||
|
||||
$lang->misc->client->versionList['2.1.1'] = '2.1.1';
|
||||
|
||||
$lang->misc->client->errorInfo = new stdclass();
|
||||
$lang->misc->client->errorInfo->downloadError = 'Failed to download package!';
|
||||
$lang->misc->client->errorInfo->configError = 'Failed to set config info!';
|
||||
$lang->misc->client->errorInfo->manualOpt = 'Please get client package from %s .';
|
||||
$lang->misc->client->errorInfo->dirNotExist = 'The dir <span class="code text-red">%s</span> is not exist, please make it.';
|
||||
$lang->misc->client->errorInfo->dirNotWritable = 'The dir <span class="code text-red">%s</span> is not writable. <br /> Please exec:<span class="code text-red">sudo chmod 777 %s</span> under linux os.';
|
||||
|
||||
$lang->misc->zentao = new stdclass();
|
||||
$lang->misc->zentao->version = 'Version %s';
|
||||
$lang->misc->zentao->labels['about'] = 'About';
|
||||
|
||||
@@ -16,7 +16,12 @@ $lang->misc->api = 'https://api.zentao.net';
|
||||
$lang->misc->enApi = 'http://api.zentao.pm';
|
||||
|
||||
$lang->misc->client = new stdclass();
|
||||
$lang->misc->client->download = '下载';
|
||||
$lang->misc->client->version = '选择版本';
|
||||
$lang->misc->client->os = '操作系统';
|
||||
$lang->misc->client->download = '下载';
|
||||
$lang->misc->client->downloading = '正在获取安装包:';
|
||||
$lang->misc->client->downloaded = '成功获取安装包';
|
||||
$lang->misc->client->setConfig = '成功设置配置信息';
|
||||
|
||||
$lang->misc->client->osList['windows64'] = 'Windows 64位';
|
||||
$lang->misc->client->osList['windows32'] = 'Windows 32位';
|
||||
@@ -24,6 +29,15 @@ $lang->misc->client->osList['linux64'] = 'Linux 64位';
|
||||
$lang->misc->client->osList['linux32'] = 'Linux 32位';
|
||||
$lang->misc->client->osList['mac'] = 'Mac版';
|
||||
|
||||
$lang->misc->client->versionList['2.1.1'] = '2.1.1';
|
||||
|
||||
$lang->misc->client->errorInfo = new stdclass();
|
||||
$lang->misc->client->errorInfo->downloadError = '获取安装包失败';
|
||||
$lang->misc->client->errorInfo->configError = '配置用户信息失败';
|
||||
$lang->misc->client->errorInfo->manualOpt = '请从 %s 手动获取安装包。';
|
||||
$lang->misc->client->errorInfo->dirNotExist = '客户端下载存储路径 <span class="code text-red">%s</span> 不存在,请创建该目录。';
|
||||
$lang->misc->client->errorInfo->dirNotWritable = '客户端下载存储路径 <span class="code text-red">%s</span> 不可写 <br />linux下面请执行命令:<span class="code text-red">sudo chmod 777 %s</span>来修正';
|
||||
|
||||
$lang->misc->zentao = new stdclass();
|
||||
$lang->misc->zentao->version = '版本%s';
|
||||
$lang->misc->zentao->labels['about'] = '关于禅道';
|
||||
|
||||
@@ -1,68 +1,111 @@
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->downloadClient;?></h2>
|
||||
<div id='' class='modal-content'>
|
||||
<div class='modal-header'>
|
||||
<h2 class='modal-title'><?php echo $lang->downloadClient;?></h2>
|
||||
</div>
|
||||
<?php if($action == 'check'):?>
|
||||
<div class='modal-body'>
|
||||
<div class='alert alert-info'>
|
||||
<p><?php echo $errorInfo;?></p>
|
||||
</div>
|
||||
<div class='text-center'><?php echo html::a($this->createLink('misc', 'downloadClient', "action=check"), $lang->refresh, '', "class='btn btn-primary btn-wide'");?></div>
|
||||
</div>
|
||||
<?php if($confirm == 'no'):?>
|
||||
<form method='post' target='hiddenwin'>
|
||||
<table class='w-p100'>
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo html::radio('os', $lang->misc->client->osList, 'windows64', '', 'block');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='text-center'>
|
||||
<td>
|
||||
<?php echo html::submitButton($lang->misc->client->download, '', 'btn btn-primary');?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<?php endif;?>
|
||||
<?php if($confirm == 'yes'):?>
|
||||
<?php if($action == 'selectPackage'):?>
|
||||
<div class='modal-body'>
|
||||
<form method='post' target='hiddenwin'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-70px'><?php echo $lang->misc->client->version;?></th>
|
||||
<td><?php echo html::select('version', $lang->misc->client->versionList, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->misc->client->os;?></th>
|
||||
<td><?php echo html::select('os', $lang->misc->client->osList, $os, "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr class='text-center'>
|
||||
<td colspan='2'><?php echo html::submitButton($lang->select, '', 'btn btn-primary btn-wide');?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
<?php if($action == 'getPackage'):?>
|
||||
<?php js::set('os', $os);?>
|
||||
<div>
|
||||
<div class='modal-body'>
|
||||
<ul>
|
||||
<li id='downloading'><?php echo $lang->misc->client->downloading;?><span>0</span>M</li>
|
||||
<li id='downloaded' class='hidden'> <?php echo $lang->misc->client->downloaded;?></li>
|
||||
<li id='setConfig' class='hidden'> <?php echo $lang->misc->client->setConfig;?></li>
|
||||
<li id='configError' class='hidden'> <?php echo $lang->misc->client->errorInfo->configError;?></li>
|
||||
<li id='downloadError' class='hidden'> <?php echo $lang->misc->client->errorInfo->downloadError;?></li>
|
||||
</ul>
|
||||
<div id='hasError' class='alert alert-info hidden'></div>
|
||||
<div id='clearTmp' class='text-center hidden'><?php echo html::a($this->createLink('misc', 'downloadClient', "action=clearTmpPackage"), $lang->confirm, '', "class='btn btn-primary btn-wide'");?></div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
getClient();
|
||||
setInterval("showDownloadProgress()", 2000);
|
||||
})
|
||||
|
||||
function getClient()
|
||||
{
|
||||
var link = createLink('misc', 'ajaxGetClient', 'os=' + os);
|
||||
var link = createLink('misc', 'ajaxGetClientPackage', 'os=' + os);
|
||||
progress = setInterval("showPackageSize()", 1000);
|
||||
$.getJSON(link, function(response)
|
||||
{
|
||||
if(response.result == 'success')
|
||||
{
|
||||
downloadClient();
|
||||
clearInterval(progress);
|
||||
$('#downloading').addClass('hidden');
|
||||
$('#downloaded').removeClass('hidden');
|
||||
|
||||
var link = createLink('misc', 'ajaxSetClientConfig', 'os=' + os);
|
||||
$.getJSON(link, function(response)
|
||||
{
|
||||
if(response.result == 'success')
|
||||
{
|
||||
$('#setConfig').removeClass('hidden');
|
||||
var link = createLink('misc', 'downloadClient', "action=downloadPackage" + '&os=' + os);
|
||||
parent.$.closeModal();
|
||||
location.href = link;
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#downloading').addClass('hidden');
|
||||
$('#configError').removeClass('hidden');
|
||||
$('#hasError').removeClass('hidden');
|
||||
$('#clearTmp').removeClass('hidden');
|
||||
$('#hasError').text(response.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
alert('fail');
|
||||
clearInterval(progress);
|
||||
$('#downloading').addClass('hidden');
|
||||
$('#downloadError').removeClass('hidden');
|
||||
$('#hasError').removeClass('hidden');
|
||||
$('#clearTmp').removeClass('hidden');
|
||||
$('#hasError').text(response.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function downloadClient()
|
||||
function showPackageSize()
|
||||
{
|
||||
var link = createLink('misc', 'downloadClient', "os=" + os + "&confirm=yes" + "&send=yes");
|
||||
location.href = link;
|
||||
}
|
||||
|
||||
function showDownloadProgress()
|
||||
{
|
||||
var link = createLink('misc', 'ajaxGetDownProgress', 'file=' + os);
|
||||
var link = createLink('misc', 'ajaxGetPackageSize', 'os=' + os);
|
||||
$.getJSON(link, function(response)
|
||||
{
|
||||
if(response.result == 'finished')
|
||||
if(response.result == 'success')
|
||||
{
|
||||
$('#downloading span').text(response.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('i');
|
||||
$('#downloading span').text(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -197,6 +197,8 @@ class my extends control
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->pager = $pager;
|
||||
|
||||
if($this->app->viewType == 'json') $this->view->tasks = array_values($this->view->tasks);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<td class='text-center'><?php echo $plan->bugs;?></td>
|
||||
<td class='text-center'><?php echo $plan->hour;?></td>
|
||||
<td class='text-center'><?php if(!empty($plan->projectID)) echo html::a(helper::createLink('project', 'task', 'projectID=' . $plan->projectID), '<i class="icon-search"></i>');?></td>
|
||||
<td title='<?php echo strip_tags($plan->desc)?>' class='text-left content'><?php echo nl2br(strip_tags($plan->desc));?></td>
|
||||
<td title='<?php echo strip_tags(str_replace("</p>", "\n", str_replace("\n", '', $plan->desc)));?>' class='text-left content'><?php echo nl2br(strip_tags(str_replace("</p>", "\n", str_replace("\n", '', $plan->desc))));?></td>
|
||||
<td class='c-actions'>
|
||||
<?php
|
||||
if(common::hasPriv('project', 'create')) echo html::a(helper::createLink('project', 'create', "projectID=©ProjectID=&planID=$plan->id"), '<i class="icon-plus"></i>', '', "class='btn' title='{$lang->project->create}'");
|
||||
|
||||
@@ -283,7 +283,7 @@ class storyModel extends model
|
||||
{
|
||||
if(empty($title)) continue;
|
||||
$story = new stdclass();
|
||||
$story->branch = $stories->branch[$i];
|
||||
$story->branch = isset($stories->branch[$i]) ? $stories->branch[$i] : 0;
|
||||
$story->module = $stories->module[$i];
|
||||
$story->plan = $stories->plan[$i];
|
||||
$story->color = $stories->color[$i];
|
||||
@@ -338,6 +338,7 @@ class storyModel extends model
|
||||
$realPath = $file['realpath'];
|
||||
unset($file['realpath']);
|
||||
|
||||
if(!is_dir($this->file->savePath)) mkdir($this->file->savePath, 0777, true);
|
||||
if(rename($realPath, $this->file->savePath . $this->file->getSaveName($file['pathname'])))
|
||||
{
|
||||
$file['addedBy'] = $this->app->user->account;
|
||||
|
||||
@@ -1338,15 +1338,15 @@ class testtaskModel extends model
|
||||
/* Set email title. */
|
||||
if($actionType == 'opened')
|
||||
{
|
||||
return sprintf($this->lang->testtask->mail->create->title, $this->app->user->realname, $testtask->id, $testtask->name);
|
||||
return sprintf($this->lang->testtask->mail->create->title, $this->app->user->realname, $testtask->id, $testtask->title);
|
||||
}
|
||||
elseif($actionType == 'closed')
|
||||
{
|
||||
return sprintf($this->lang->testtask->mail->close->title, $this->app->user->realname, $testtask->id, $testtask->name);
|
||||
return sprintf($this->lang->testtask->mail->close->title, $this->app->user->realname, $testtask->id, $testtask->title);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sprintf($this->lang->testtask->mail->edit->title, $this->app->user->realname, $testtask->id, $testtask->name);
|
||||
return sprintf($this->lang->testtask->mail->edit->title, $this->app->user->realname, $testtask->id, $testtask->title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ if(file_exists('install.php') or file_exists('upgrade.php'))
|
||||
|
||||
/* If client device is mobile and version is pro, set the default view as mthml. */
|
||||
if($app->clientDevice == 'mobile' and (strpos($config->version, 'pro') === 0 or strpos($config->version, 'biz') === 0) and $config->default->view == 'html') $config->default->view = 'mhtml';
|
||||
if(!empty($_GET['display']) && $_GET['display'] == 'card') $config->default->view = 'xhtml';
|
||||
|
||||
$app->parseRequest();
|
||||
$common->checkPriv();
|
||||
|
||||
+20
-2
@@ -667,17 +667,35 @@ function notifyMessage(data)
|
||||
{
|
||||
if(window.Notification)
|
||||
{
|
||||
var notify = null;
|
||||
|
||||
message = data;
|
||||
if(typeof data.message == 'string') message = data.message;
|
||||
if(Notification.permission == "granted")
|
||||
{
|
||||
new Notification("", {body:data});
|
||||
notify = new Notification("", {body:message, tag:'zentao', data:data});
|
||||
}
|
||||
else if(Notification.permission != "denied")
|
||||
{
|
||||
Notification.requestPermission(function(permission)
|
||||
{
|
||||
new Notification("", {body:data});
|
||||
notify = new Notification("", {body:message, tag:'zentao', data:data});
|
||||
});
|
||||
}
|
||||
|
||||
if(notify)
|
||||
{
|
||||
notify.onclick = function()
|
||||
{
|
||||
window.focus();
|
||||
if(typeof notify.data.url == 'string' && notify.data.url) window.location.href = notify.data.url;
|
||||
notify.close();
|
||||
}
|
||||
setTimeout(function()
|
||||
{
|
||||
notify.close();
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../../common/view/header.modal.html.php';?>
|
||||
<form id='jaxForm' class='form-horizontal' action='<?php echo inlink('downloadxxd')?>' method='post' target='_blank'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
@@ -61,7 +60,6 @@
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<?php include '../../../common/view/footer.modal.html.php';?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
<?php
|
||||
$lang->message->typeList['xuanxuan'] = 'Xuanxuan';
|
||||
|
||||
$lang->message->sender = 'ZentaoPMS';
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
<?php
|
||||
$lang->message->typeList['xuanxuan'] = '喧喧';
|
||||
|
||||
$lang->message->sender = '禅道项目管理';
|
||||
|
||||
@@ -21,8 +21,10 @@ class xuanxuanMessage extends messageModel
|
||||
if(!empty($object->assignedTo)) $target .= $object->assignedTo;
|
||||
if(!empty($object->mailto)) $target .= ",{$object->mailto}";
|
||||
$target = trim($target, ',');
|
||||
$target = $this->dao->select('id')->from(TABLE_USER)->where('account')->in($target)->fetchAll('id');
|
||||
$target = array_keys($target);
|
||||
|
||||
if($target) $this->loadModel('chat')->createNotify($target, $text, '', $text, 'text', $url);
|
||||
if($target) $this->loadModel('chat')->createNotify($target, $text, '', '', 'text', $url, array(), array('id' => 'zentao', 'realname' => $this->lang->message->sender, 'name' => $this->lang->message->sender));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user