control.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <?php
  2. /**
  3. * The control file of client module of XXB.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd., www.zentao.net)
  6. * @license ZOSL (https://zpl.pub/page/zoslv1.html)
  7. * @author Gang Liu <liugang@cnezsoft.com>
  8. * @package client
  9. * @version $Id$
  10. * @link https://xuanim.com
  11. */
  12. class client extends control
  13. {
  14. /**
  15. * Index page.
  16. *
  17. * @access public
  18. * @return void
  19. */
  20. public function index()
  21. {
  22. $blocks = $this->loadModel('block')->getBlockList('xxb');
  23. /* Init block when vist index first. */
  24. if(empty($blocks))
  25. {
  26. if($this->loadModel('block')->initBlock('xxb')) die(js::reload());
  27. }
  28. foreach($blocks as $key => $block)
  29. {
  30. $block->params = json_decode($block->params);
  31. if(empty($block->params)) $block->params = new stdclass();
  32. $sign = $this->config->requestType == 'PATH_INFO' ? '?' : '&';
  33. $block->blockLink = $this->createLink('block', 'print' . $block->block . 'block', "index={$block->id}");
  34. }
  35. $this->view->title = $this->lang->client->common;
  36. $this->view->blocks = $blocks;
  37. $this->view->currentVersion = $this->client->getCurrentVersion();
  38. $this->view->versionApiUrl = sprintf($this->config->client->upgradeApi, '');
  39. $this->display();
  40. }
  41. /**
  42. * Browse client list.
  43. *
  44. * @access public
  45. * @return void
  46. */
  47. public function browse()
  48. {
  49. $this->view->title = $this->lang->client->update;
  50. $this->view->clients = $this->client->getList();
  51. $this->display();
  52. }
  53. /**
  54. * Create a client.
  55. *
  56. * @access public
  57. * @return void
  58. */
  59. public function create()
  60. {
  61. if($_POST)
  62. {
  63. $this->client->create();
  64. if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
  65. $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
  66. }
  67. $this->view->title = $this->lang->client->create;
  68. $this->display();
  69. }
  70. /**
  71. * Download remote package.
  72. * @param string $version
  73. * @param string $link
  74. * @param string $os
  75. * @return string
  76. */
  77. public function download($version = '', $link = '', $os = '')
  78. {
  79. set_time_limit(0);
  80. $result = $this->client->downloadZipPackage($version, $link);
  81. if($result == false) $this->send(array('result' => 'fail', 'message' => $this->lang->client->downloadFail));
  82. $client = $this->client->edit($version, $result, $os);
  83. if($client == false) $this->send(array('result' => 'fail', 'message' => $this->lang->client->saveClientError));
  84. $this->send(array('result' => 'success', 'client' => $client, 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
  85. }
  86. /**
  87. * Edit a version.
  88. *
  89. * @param int $clientID
  90. * @access public
  91. * @return void
  92. */
  93. public function edit($clientID)
  94. {
  95. if($_POST)
  96. {
  97. $this->client->update($clientID);
  98. if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
  99. $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
  100. }
  101. $this->view->title = $this->lang->client->edit;
  102. $this->view->client = $this->client->getByID($clientID);
  103. $this->display();
  104. }
  105. /**
  106. * View changelog of a client update
  107. *
  108. * @param int $clientID
  109. * @access public
  110. * @return void
  111. */
  112. public function changelog($clientID)
  113. {
  114. $client = $this->client->getByID($clientID);
  115. $this->view->client = $client;
  116. $this->view->title = $this->lang->client->changeLog . ' ' . $client->version;
  117. $this->display();
  118. }
  119. /**
  120. * Delete a client.
  121. *
  122. * @param int $clientID
  123. * @access public
  124. * @return void
  125. */
  126. public function delete($clientID)
  127. {
  128. $this->dao->delete()->from(TABLE_IM_CLIENT)->where('id')->eq($clientID)->exec();
  129. if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
  130. $this->send(array('result' => 'success'));
  131. }
  132. /**
  133. * Check upgrade.
  134. *
  135. * @access public
  136. * @return void
  137. */
  138. public function checkUpgrade()
  139. {
  140. $currentVersion = $this->client->getCurrentVersion();
  141. $apiUrl = sprintf($this->config->client->upgradeApi, "-$currentVersion->version");
  142. $jsonData = file_get_contents($apiUrl);
  143. $serverVersions = json_decode($jsonData, false);
  144. $this->view->title = $this->lang->client->checkUpgrade;
  145. $this->view->serverVersions = $serverVersions;
  146. $this->view->versions = $serverVersions;
  147. $this->view->currentVersion = $currentVersion;
  148. $this->view->path = $this->app->dataRoot;
  149. $this->display();
  150. }
  151. /**
  152. * Download xuan client.
  153. *
  154. * @access public
  155. * @param string $action
  156. * @param string $os
  157. * @return void
  158. */
  159. public function downloadClient($action = 'check', $os = '')
  160. {
  161. if($_POST)
  162. {
  163. $os = $this->post->os;
  164. die(js::locate($this->createLink('client', 'downloadClient', "action=getPackage&os=$os"), 'self'));
  165. }
  166. if($action == 'check')
  167. {
  168. $error = false;
  169. $errorInfo = '';
  170. $clientDir = $this->app->wwwRoot . 'data/client/' . $this->config->xuanxuan->version . '/';
  171. if(!is_dir($clientDir))
  172. {
  173. $result = mkdir($clientDir, 0755, true);
  174. if($result == false)
  175. {
  176. $error = true;
  177. $errorInfo = sprintf($this->lang->client->errorInfo->dirNotExist, $clientDir, $clientDir);
  178. }
  179. }
  180. if(!is_writable($clientDir))
  181. {
  182. $error = true;
  183. $errorInfo = sprintf($this->lang->client->errorInfo->dirNotWritable, $clientDir, $clientDir);
  184. }
  185. $this->view->error = $error;
  186. $this->view->errorInfo = $errorInfo;
  187. if(!$error) die(js::locate($this->createLink('client', 'downloadClient', "action=selectPackage")));
  188. }
  189. if($action == 'selectPackage')
  190. {
  191. $os = 'win64';
  192. $agentOS = helper::getOS();
  193. if(strpos($agentOS, 'Windows') !== false) $os = 'win64';
  194. if(strpos($agentOS, 'Linux') !== false) $os = 'linux64';
  195. if(strpos($agentOS, 'Mac') !== false) $os = 'mac';
  196. $this->view->os = $os;
  197. }
  198. if($action == 'getPackage')
  199. {
  200. $this->view->os = $os;
  201. $this->view->account = $this->app->user->account;
  202. }
  203. if($action == 'clearTmpPackage')
  204. {
  205. $account = $this->app->user->account;
  206. $tmpDir = $this->app->wwwRoot . 'data/client/' . "$account/";
  207. if(is_dir($tmpDir))
  208. {
  209. $zfile = $this->app->loadClass('zfile');
  210. $zfile->removeDir($tmpDir);
  211. }
  212. }
  213. if($action == 'downloadPackage')
  214. {
  215. $account = $this->app->user->account;
  216. $clientDir = $this->app->wwwRoot . 'data/client/' . "$account/";
  217. $clientFile = $clientDir . 'xuanxuan.zip';
  218. $zipContent = file_get_contents($clientFile);
  219. if(is_dir($clientDir))
  220. {
  221. $zfile = $this->app->loadClass('zfile');
  222. $zfile->removeDir($clientDir);
  223. }
  224. $output = $this->fetch('file', 'sendDownHeader', array('fileName' => "xuanxuan." . $os . '.zip', 'zip', $zipContent));
  225. }
  226. $this->view->action = $action;
  227. $this->display();
  228. }
  229. /**
  230. * Ajax get client package.
  231. *
  232. * @param string $os
  233. * @access public
  234. * @return void
  235. */
  236. public function ajaxGetClientPackage($os = '')
  237. {
  238. set_time_limit (0);
  239. session_write_close();
  240. $response = array();
  241. $response['result'] = 'success';
  242. $response['message'] = '';
  243. $clientDir = $this->app->wwwRoot . 'data/client/';
  244. if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
  245. $version = $this->config->xuanxuan->version;
  246. $packageDir = $clientDir . "/$version/";
  247. if(!is_dir($packageDir)) mkdir($packageDir, 0755, true);
  248. $account = $this->app->user->account;
  249. $tmpDir = $clientDir . "/$account/";
  250. if(!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);
  251. $needCache = false;
  252. $clientName = "xuanxuan." . $version . "." . $os . ".zip";
  253. $packageFile = $packageDir . $clientName;
  254. $packageURL = "http://dl.cnezsoft.com/xuanxuan/$version/$clientName";
  255. if(!file_exists($packageFile))
  256. {
  257. $xxFile = $packageURL . "?t=" . rand();
  258. $needCache = true;
  259. }
  260. else
  261. {
  262. $xxFile = $packageFile;
  263. }
  264. $clientFile = $tmpDir . 'xuanxuan.zip';
  265. if($xxHd = fopen($xxFile, "rb"))
  266. {
  267. if($clientHd = fopen($clientFile, "wb"))
  268. {
  269. while(!feof($xxHd))
  270. {
  271. $result = fwrite($clientHd, fread($xxHd, 1024 * 8 ), 1024 * 8 );
  272. if($result == false)
  273. {
  274. $response['result'] = 'fail';
  275. $response['message'] = sprintf($this->lang->client->errorInfo->manualOpt, $packageURL);
  276. $this->send($response);
  277. }
  278. }
  279. }
  280. else
  281. {
  282. $response['result'] = 'fail';
  283. $response['message'] = sprintf($this->lang->client->errorInfo->manualOpt, $packageURL);
  284. $this->send($response);
  285. }
  286. fclose($xxHd);
  287. fclose($clientHd);
  288. }
  289. else
  290. {
  291. $response['result'] = 'fail';
  292. $response['message'] = sprintf($this->lang->client->errorInfo->manualOpt, $packageURL);
  293. $this->send($response);
  294. }
  295. if($needCache) file_put_contents($packageFile, file_get_contents($clientFile));
  296. $this->send($response);
  297. }
  298. /**
  299. * Ajax get client package size.
  300. *
  301. * @access public
  302. * @return void
  303. */
  304. public function ajaxGetPackageSize()
  305. {
  306. $account = $this->app->user->account;
  307. $packageFile = $this->app->wwwRoot . 'data/client/' . $account . '/xuanxuan.zip';
  308. $size = 0;
  309. if(file_exists($packageFile))
  310. {
  311. $size = filesize($packageFile);
  312. $size = $size ? round($size / 1048576, 2) : 0;
  313. }
  314. $response = array();
  315. $response['result'] = 'success';
  316. $response['size'] = $size;
  317. $this->send($response);
  318. }
  319. /**
  320. * Ajax set client config to client package.
  321. *
  322. * @param string $os
  323. * @access public
  324. * @return void
  325. */
  326. public function ajaxSetClientConfig($os = '')
  327. {
  328. $response['result'] = 'success';
  329. $account = $this->app->user->account;
  330. $clientDir = $this->app->wwwRoot . 'data/client/' . "$account/";
  331. if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
  332. /* write login info into config file. */
  333. $loginInfo = new stdclass();
  334. $loginInfo->ui = new stdclass();
  335. $loginInfo->ui->defaultUser = new stdclass();
  336. $loginInfo->ui->defaultUser->server = $this->config->xuanxuan->server;
  337. $loginInfo->ui->defaultUser->account = $this->app->user->account;
  338. $loginInfo = json_encode($loginInfo);
  339. $loginFile = $clientDir . 'config.json';
  340. file_put_contents($loginFile, $loginInfo);
  341. define('PCLZIP_TEMPORARY_DIR', $clientDir);
  342. $this->app->loadClass('pclzip', true);
  343. $clientFile = $clientDir . 'xuanxuan.zip';
  344. $archive = new pclzip($clientFile);
  345. if($os == 'mac')
  346. {
  347. $result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'xuanxuan.app/Contents/Resources/build-in');
  348. }
  349. else
  350. {
  351. $result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'xuanxuan/resources/build-in');
  352. }
  353. if($result == 0)
  354. {
  355. $response['result'] = 'fail';
  356. $response['message'] = $archive->errorInfo(true);
  357. $this->send($response);
  358. }
  359. $this->send($response);
  360. }
  361. /**
  362. * Fetch and pack server address into client zips, and provide download links.
  363. *
  364. * @param string $os
  365. * @return void
  366. */
  367. public function getClientLinks($os = 'win64')
  368. {
  369. if($_POST)
  370. {
  371. $os = implode(',', $this->post->os);
  372. $this->client->fetchCurrentClient($os);
  373. $this->client->packServerConfig($os);
  374. $this->view->links = $this->client->getLinks($os);
  375. $this->view->os = '';
  376. $this->display();
  377. die;
  378. }
  379. $this->view->hangWarning = $this->lang->client->serverMightHang;
  380. $this->view->links = false;
  381. $this->view->os = $os;
  382. $this->display();
  383. }
  384. }