This commit is contained in:
Yagami
2018-12-12 10:58:05 +08:00
24 changed files with 509 additions and 112 deletions
+2
View File
@@ -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
View File
@@ -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'; // 请求类型为GETsession变量名。 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();
+117
View File
@@ -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);
}
}
+34
View File
@@ -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';
}
}
}
+1 -1
View File
@@ -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'") . ' &nbsp; ';
echo html::a(helper::createLink('misc', 'downloadClient', '', '', true), "<i class='icon-bell'></i>", '', "title='$lang->downloadClient' class='text-primary iframe' data-width='600'") . ' &nbsp; ';
}
/**
+1 -1
View File
@@ -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);
}
}
});
+2 -2
View File
@@ -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>
+2 -2
View File
@@ -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>
+5 -5
View File
@@ -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>
+4 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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';
+15 -1
View File
@@ -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'] = '关于禅道';
+77 -34
View File
@@ -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);
}
});
}
+2
View File
@@ -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();
}
+1 -1
View File
@@ -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=&copyProjectID=&planID=$plan->id"), '<i class="icon-plus"></i>', '', "class='btn' title='{$lang->project->create}'");
+2 -1
View File
@@ -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;
+3 -3
View File
@@ -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);
}
}
+1
View File
@@ -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
View File
@@ -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));
}
}
}