model.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. /**
  3. * The model file of store module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Jianhua Wang <wangjanhua@easycorp.ltd>
  8. * @package store
  9. * @version $Id$
  10. * @link https://www.zentao.net
  11. */
  12. class storeModel extends model
  13. {
  14. /**
  15. * Construct function: set api headers.
  16. *
  17. * @param string $appName
  18. * @access public
  19. * @return void
  20. */
  21. public function __construct($appName = '')
  22. {
  23. parent::__construct($appName);
  24. global $config, $app;
  25. $config->cloud->api->headers[] = "{$config->cloud->api->auth}: {$config->cloud->api->token}";
  26. if($config->cloud->api->switchChannel && $app->session->cloudChannel) $config->cloud->api->channel = $app->session->cloudChannel;
  27. }
  28. /**
  29. * 根据关键字查询应用市场应用列表。
  30. * Get app list from cloud market.
  31. *
  32. * @param string $orderBy
  33. * @param string $keyword
  34. * @param int $categories
  35. * @param int $page
  36. * @param int $pageSize
  37. * @access public
  38. * @return object
  39. * @param int $categoryID
  40. */
  41. public function searchApps($orderBy = '', $keyword = '', $categoryID = 0, $page = 1, $pageSize = 20)
  42. {
  43. $params = array(
  44. 'channel' => $this->config->cloud->api->channel,
  45. 'q' => trim($keyword),
  46. 'exclude' => 'zentao*',
  47. 'sort' => trim($orderBy),
  48. 'page_size' => $pageSize,
  49. 'page' => $page
  50. );
  51. if($categoryID) $params['category'] = $categoryID;
  52. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  53. $params['zentao_version'] = str_replace('_', '.', $ztVersion);
  54. $apiUrl = "{$this->config->cloud->api->host}/api/market/applist?";
  55. $apiUrl .= http_build_query($params);
  56. $result = commonModel::apiGet($apiUrl, array(), $this->config->cloud->api->headers);
  57. $pagedApps = new stdclass();
  58. $pagedApps->apps = array();
  59. $pagedApps->total = 0;
  60. if(empty($result) || $result->code != 200) return $pagedApps;
  61. $pagedApps->apps = $result->data->apps;
  62. $pagedApps->total = $result->data->total;
  63. return $pagedApps;
  64. }
  65. /**
  66. * 通过接口获取应用详情。
  67. * Get app info from cloud market.
  68. *
  69. * @param int $appID
  70. * @param boolean $analysis true: log this request for analysis.
  71. * @param string $name
  72. * @param string $version
  73. * @param string $channel
  74. * @access public
  75. * @return object|null
  76. */
  77. public function getAppInfo($appID = 0, $analysis = false, $name = '', $version = '', $channel = '')
  78. {
  79. if(empty($appID) && empty($name)) return null;
  80. if(empty($channel)) $channel = $this->config->cloud->api->channel;
  81. $apiParams = array();
  82. $apiParams['analysis'] = $analysis ? 'true' : 'false' ;
  83. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  84. $apiParams['zentao_version'] = str_replace('_', '.', $ztVersion);
  85. if($appID) $apiParams['id'] = $appID;
  86. if($name) $apiParams['name'] = $name;
  87. if($version) $apiParams['version'] = $version;
  88. if($channel) $apiParams['channel'] = $channel;
  89. $apiUrl = $this->config->cloud->api->host;
  90. $apiUrl .= '/api/market/appinfo';
  91. $result = commonModel::apiGet($apiUrl, $apiParams, $this->config->cloud->api->headers);
  92. if(!isset($result->code) || $result->code != 200) return null;
  93. return $result->data;
  94. }
  95. /**
  96. * 根据名称查询多个应用信息。
  97. * Get app infos map by name array from cloud market.
  98. *
  99. * @param array $nameList
  100. * @access public
  101. * @return object|null
  102. * @param string $channel
  103. */
  104. public function getAppMapByNames($nameList = array(), $channel = 'stable')
  105. {
  106. $apiParams = array('name_list' => $nameList, 'channel' => $channel);
  107. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  108. $apiParams['zentao_version'] = str_replace('_', '.', $ztVersion);
  109. $apiUrl = $this->config->cloud->api->host;
  110. $apiUrl .= '/api/market/app_info_list';
  111. $result = commonModel::apiPost($apiUrl, $apiParams, $this->config->cloud->api->headers);
  112. if(!isset($result->code) || $result->code != 200) return null;
  113. return $result->data;
  114. }
  115. /**
  116. * Get app version pairs by id.
  117. *
  118. * @param int $appID
  119. * @access public
  120. * @return array
  121. */
  122. public function getVersionPairs($appID)
  123. {
  124. $pairs = array();
  125. $versions = $this->appVersionList($appID);
  126. foreach($versions as $version) $pairs[$version->version] = $version->app_version . '-' . $version->version;
  127. return $pairs;
  128. }
  129. /**
  130. * 获取应用的可安装版本。
  131. * Get app version list to install.
  132. *
  133. * @param int $appID
  134. * @param string $name
  135. * @param string $channel
  136. * @param int $page
  137. * @param int $pageSize
  138. * @access public
  139. * @return array
  140. */
  141. public function appVersionList($appID, $name = '', $channel = '', $page = 1, $pageSize = 3)
  142. {
  143. $apiParams = array();
  144. $apiParams['page'] = $page;
  145. $apiParams['page_size'] = $pageSize;
  146. if($appID) $apiParams['id'] = $appID;
  147. if($name) $apiParams['name'] = $name;
  148. if($channel) $apiParams['channel'] = $channel;
  149. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  150. $apiParams['zentao_version'] = str_replace('_', '.', $ztVersion);
  151. $apiUrl = $this->config->cloud->api->host;
  152. $apiUrl .= '/api/market/app/version';
  153. $result = commonModel::apiGet($apiUrl, $apiParams, $this->config->cloud->api->headers);
  154. if(!isset($result->code) || $result->code != 200) return array();
  155. return array_combine(helper::arrayColumn($result->data, 'version'), $result->data);
  156. }
  157. /**
  158. * 获取应用可以升级到的版本。
  159. * Get upgradable versions of app from cloud market.
  160. *
  161. * @param string $currentVersion
  162. * @param int $appID appID is required if no appName.
  163. * @param string $appName appName is required if no appID.
  164. * @param string $channel
  165. * @access public
  166. * @return array
  167. */
  168. public function getUpgradableVersions($currentVersion, $appID = 0, $appName = '', $channel = '')
  169. {
  170. $channel = $channel ? $channel : $this->config->cloud->api->channel;
  171. $apiUrl = $this->config->cloud->api->host;
  172. $apiUrl .= '/api/market/app/version/upgradable';
  173. $conditions = array('version' => $currentVersion, 'channel' => $channel);
  174. if($appID)
  175. {
  176. $conditions['id'] = $appID;
  177. }
  178. else
  179. {
  180. $conditions['name'] = $appName;
  181. }
  182. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  183. $conditions['zentao_version'] = str_replace('_', '.', $ztVersion);
  184. $result = commonModel::apiGet($apiUrl, $conditions, $this->config->cloud->api->headers);
  185. if(!isset($result->code) || $result->code != 200) return array();
  186. return $result->data;
  187. }
  188. /**
  189. * 获取应用的最新版本。
  190. * Get the latest versions of app from cloud market.
  191. *
  192. * @param int $appID
  193. * @param string $currentVersion
  194. * @access public
  195. * @return object|null
  196. */
  197. public function appLatestVersion($appID, $currentVersion)
  198. {
  199. $versionList = $this->getUpgradableVersions($currentVersion, $appID);
  200. $latestVersion = $this->pickHighestVersion($versionList);
  201. if(empty($latestVersion)) return null;
  202. if(version_compare(str_replace('-', '.', $latestVersion->version), str_replace('-', '.', $currentVersion), '>')) return $latestVersion;
  203. return null;
  204. }
  205. /**
  206. * 从版本列表中选择最高版本并进行比较。
  207. * Pick highest version from version list and compared version.
  208. *
  209. * @param array $versionList
  210. * @access public
  211. * @return object|null
  212. */
  213. public function pickHighestVersion($versionList)
  214. {
  215. if(empty($versionList)) return null;
  216. $highestVersion = new stdclass();
  217. $highestVersion->version = '0.0.0';
  218. foreach($versionList as $version)
  219. {
  220. if(version_compare(str_replace('-', '.', $version->version), str_replace('-', '.', $highestVersion->version), '>')) $highestVersion = $version;
  221. }
  222. return $highestVersion;
  223. }
  224. /**
  225. * 从云市场获取类别列表。
  226. * Get category list from cloud market.
  227. *
  228. * @access public
  229. * @return object
  230. */
  231. public function getCategories()
  232. {
  233. $apiUrl = $this->config->cloud->api->host;
  234. $apiUrl .= '/api/market/categories';
  235. $result = commonModel::apiGet($apiUrl, array(), $this->config->cloud->api->headers);
  236. if($result->code == 200) return $result->data;
  237. $categories = new stdclass;
  238. $categories->categories = array();
  239. $categories->total = 0;
  240. return $categories;
  241. }
  242. /**
  243. * 从渠成获取应用动态消息。
  244. * Get app dynamic news from Qucheng offical site.
  245. *
  246. * @param object $cloudApp
  247. * @param int $pageID
  248. * @param int $recPerPage
  249. * @access public
  250. * @return object|null
  251. */
  252. public function appDynamic($cloudApp, $pageID = 1, $recPerPage = 20)
  253. {
  254. $alias = strtolower(str_replace('-', '', $cloudApp->chart));
  255. $url = $this->config->store->quchengSiteHost . "/article-apibrowse-{$alias}-{$pageID}-{$recPerPage}.html";
  256. $result = commonModel::apiGet($url);
  257. if($result && $result->code == 200) return $result->data;
  258. return null;
  259. }
  260. /**
  261. * 设置应用最新版本。
  262. * Set app latest version.
  263. *
  264. * @param array $appList
  265. * @access public
  266. * @return array
  267. */
  268. public function batchSetLatestVersions($appList)
  269. {
  270. $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
  271. $apiUrl = "{$this->config->cloud->api->host}/api/market/applist/version/upgradable?zentao_version=" . str_replace('_', '.', $ztVersion);
  272. $data = array();
  273. foreach($appList as $app)
  274. {
  275. $data[] = array(
  276. 'version' => $app->version,
  277. 'channel' => $this->config->cloud->api->channel,
  278. 'id' => $app->appID
  279. );
  280. }
  281. $result = json_decode(common::http($apiUrl, $data, array(), $this->config->cloud->api->headers, 'json'));
  282. if(!isset($result->code) || $result->code != 200) return $appList;
  283. $versionList = array();
  284. foreach($result->data as $app)
  285. {
  286. $latestVersion = $this->pickHighestVersion($app->versions);
  287. $versionList[$app->id] = empty($latestVersion) ? '' : $latestVersion->version;
  288. }
  289. foreach($appList as $app) $app->latestVersion = $versionList[$app->appID];
  290. return $appList;
  291. }
  292. }