cloud.mod.php 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. defined('IN_IA') or exit('Access Denied');
  7. function cloud_client_define() {
  8. return array(
  9. '/framework/function/communication.func.php',
  10. '/framework/model/cloud.mod.php',
  11. '/web/source/cloud/upgrade.ctrl.php',
  12. '/web/source/cloud/dock.ctrl.php',
  13. '/web/themes/default/cloud/upgrade.html',
  14. );
  15. }
  16. function cloud_not_must_authorization_method() {
  17. return array(
  18. 'module/setting/index',
  19. 'module/setting/save',
  20. 'sms/info',
  21. 'sms/sign',
  22. 'wxapp/info',
  23. 'wxapp/login/qr-code',
  24. 'wxapp/login/qr-scan',
  25. 'wxapp/publish',
  26. 'wxapp/publish/download',
  27. 'module/query',
  28. 'theme/query',
  29. 'we7/oauth/user-bind/mobile-bind-info',
  30. 'we7/oauth/user-bind/mobile-code',
  31. 'we7/oauth/user-bind/complete',
  32. 'we7/oauth/user-bind/info',
  33. 'we7/oauth/user-bind/complete-with-accesstoken',
  34. 'we7/site/console/visible',
  35. 'we7/site/console/index-url',
  36. 'we7/site/console/share-url',
  37. 'site/oauth/user/web-token/verify',
  38. 'site/oauth/register-url/index',
  39. 'site/oauth/user/info',
  40. 'site/token/index',
  41. 'site/oauth/login-url/index',
  42. 'site/oauth/access-token/code',
  43. );
  44. }
  45. function _cloud_build_params($must_authorization_host = true) {
  46. global $_W;
  47. $pars = array();
  48. $pars['host'] = strexists($_SERVER['HTTP_HOST'], ':') ? parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST) : $_SERVER['HTTP_HOST'];
  49. if (is_array($_W['setting']['site']) && !empty($_W['setting']['site']['url']) && !$must_authorization_host) {
  50. $pars['host'] = parse_url($_W['setting']['site']['url'], PHP_URL_HOST);
  51. }
  52. $pars['https'] = $_W['ishttps'] ? 1 : 0;
  53. $pars['family'] = IMS_FAMILY;
  54. $pars['version'] = IMS_VERSION;
  55. $pars['php_version'] = PHP_VERSION;
  56. $pars['current_host'] = $_SERVER['HTTP_HOST'];
  57. $pars['release'] = IMS_RELEASE_DATE;
  58. if (!empty($_W['setting']['site'])) {
  59. $pars['key'] = $_W['setting']['site']['key'];
  60. $pars['password'] = md5($_W['setting']['site']['key'] . $_W['setting']['site']['token']);
  61. }
  62. $clients = cloud_client_define();
  63. $string = '';
  64. foreach ($clients as $cli) {
  65. $string .= md5_file(IA_ROOT . $cli);
  66. }
  67. $pars['client'] = md5($string);
  68. return $pars;
  69. }
  70. function _cloud_shipping_parse($dat, $file) {
  71. if (is_error($dat)) {
  72. return error(-1, '网络传输故障,详情: ' . (strpos($dat['message'], 'Connection reset by peer') ? '云服务瞬时访问过大而导致网络传输中断,请稍后重试。' : $dat['message']));
  73. }
  74. $tmp = iunserializer($dat['content']);
  75. if (is_array($tmp) && is_error($tmp)) {
  76. if ($tmp['errno'] == '-2') {
  77. file_put_contents(IA_ROOT . '/framework/version.inc.php', str_replace("'x'", "'v'", file_get_contents(IA_ROOT . '/framework/version.inc.php')));
  78. }
  79. if ($tmp['errno'] == 401) {
  80. register_shutdown_function('cloud_reset_siteinfo');
  81. $tmp['message'] = '<div class="text-left"><span class="text-left">1.本域名为非微擎授权域名,系统已帮您自动重置,请使用授权域名访问或 <a href="">刷新重试</a>!</span><br><span class="text-left">2.如您已操作域名修改,请配置当前站点域名访问和https证书!</span><br><span class="text-left">3.刷新后若仍未解决请 <a target="_blank" href="https://task.w7.com/taskrelease?type_id=11&team_id=1">提交工单</a>!</span></div>';
  82. }
  83. return $tmp;
  84. }
  85. if ($dat['content'] == 'patching') {
  86. return error(-1, '补丁程序正在更新中,请稍后再试!');
  87. }
  88. if ($dat['content'] == 'frequent') {
  89. return error(-1, '更新操作太频繁,请稍后再试!');
  90. }
  91. if ($dat['content'] == 'blacklist') {
  92. return error(-1, '抱歉,您的站点已被列入云服务黑名单,云服务一切业务已被禁止,请联系微擎客服!');
  93. }
  94. if ($dat['content'] == 'install-theme-protect' || $dat['content'] == 'install-module-protect') {
  95. return error('-1', '此' . ($dat['content'] == 'install-theme-protect' ? '模板' : '模块') . '已设置版权保护,您只能通过云平台来安装,请先删除该模块的所有文件,购买后再行安装。');
  96. }
  97. $content = json_decode($dat['content'], true);
  98. if (!empty($content['error'])) {
  99. return error(-1, $content['error']);
  100. }
  101. if (!empty($content) && is_array($content)) {
  102. return $content;
  103. }
  104. if (strlen($dat['content']) != 32) {
  105. $dat['content'] = iunserializer($dat['content']);
  106. if (is_array($dat['content']) && isset($dat['content']['files'])) {
  107. if (!empty($dat['content']['manifest'])) {
  108. $dat['content']['manifest'] = base64_decode($dat['content']['manifest']);
  109. }
  110. if (!empty($dat['content']['scripts'])) {
  111. $dat['content']['scripts'] = base64_decode($dat['content']['scripts']);
  112. }
  113. return $dat['content'];
  114. }
  115. if (is_array($dat['content']) && isset($dat['content']['data'])) {
  116. $data = $dat['content'];
  117. } else {
  118. return error(-1, '云服务平台向您的服务器传输数据过程中出现错误,详情:' . $dat['content']);
  119. }
  120. } else {
  121. $data = @file_get_contents($file);
  122. @unlink($file);
  123. }
  124. $ret = @iunserializer($data);
  125. if (empty($data) || empty($ret)) {
  126. return error(-1, '云服务平台向您的服务器传输的数据校验失败.可尝试:1、更新缓存 2、云服务诊断');
  127. }
  128. $ret = iunserializer($ret['data']);
  129. if (is_array($ret) && is_error($ret)) {
  130. if ($ret['errno'] == '-2') {
  131. file_put_contents(IA_ROOT . '/framework/version.inc.php', str_replace("'x'", "'v'", file_get_contents(IA_ROOT . '/framework/version.inc.php')));
  132. }
  133. if ($ret['errno'] == '-3') {
  134. return array(
  135. 'errno' => $ret['errno'],
  136. 'message' => $ret['message'],
  137. 'cloud_id' => $ret['data'],
  138. );
  139. }
  140. }
  141. if (!is_error($ret) && is_array($ret)) {
  142. if (!empty($ret) && !empty($ret['state']) && $ret['state'] == 'fatal') {
  143. return error($ret['errorno'], '发生错误: ' . $ret['message']);
  144. }
  145. return $ret;
  146. } else {
  147. return error($ret['errno'], "发生错误: {$ret['message']}");
  148. }
  149. }
  150. function cloud_request($url, $post = '', $extra = array(), $timeout = 60) {
  151. global $_W;
  152. load()->func('communication');
  153. if (!empty($_W['setting']['cloudip']['ip']) && empty($extra['ip'])) {
  154. $extra['ip'] = $_W['setting']['cloudip']['ip'];
  155. }
  156. if (strexists($url, 's.w7.cc')) {
  157. $extra = array();
  158. }
  159. $response = ihttp_request($url, $post, $extra, $timeout);
  160. if (is_error($response)) {
  161. setting_save(array(), 'cloudip');
  162. }
  163. return $response;
  164. }
  165. function cloud_api($method, $data = array(), $extra = array(), $timeout = 60) {
  166. global $_W;
  167. $cache_key = cache_system_key('cloud_api', array('method' => md5($method . json_encode($data))));
  168. $cache = cache_load($cache_key);
  169. $extra['use_cache'] = !isset($extra['use_cache']) || !empty($extra['use_cache']) ? true : false;
  170. if (!empty($cache) && $extra['use_cache']) {
  171. return $cache;
  172. }
  173. $api_url = CLOUD_API_DOMAIN . '/%s';
  174. $not_must_authorization_method = cloud_not_must_authorization_method();
  175. $must_authorization_host = !in_array($method, $not_must_authorization_method);
  176. $pars = _cloud_build_params($must_authorization_host);
  177. if ($method != 'site/token/index') {
  178. $pars['token'] = cloud_build_transtoken();
  179. }
  180. $data = array_merge($pars, $data);
  181. if (starts_with($_SERVER['HTTP_USER_AGENT'], 'we7')) {
  182. $extra['CURLOPT_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
  183. }
  184. if (!empty($_W['config']['setting']['useragent']) && starts_with($_W['config']['setting']['useragent'], 'we7')) {
  185. $extra['CURLOPT_USERAGENT'] = $_W['config']['setting']['useragent'];
  186. }
  187. $extra['X-We7-Cache'] = cache_random(4, $extra['use_cache']);
  188. $response = ihttp_request(sprintf($api_url, $method), $data, $extra, $timeout);
  189. $file = IA_ROOT . '/data/' . (!empty($data['file']) ? $data['file'] : str_replace('/', '', $method));
  190. $file = $file . cache_random();
  191. $ret = _cloud_shipping_parse($response, $file);
  192. if (is_error($ret)) {
  193. WeUtility::logging('cloud-api-error', array('method' => sprintf($api_url, $method), 'data' => $data, 'extra' => $extra, 'response' => $response), true);
  194. }
  195. if (!is_error($ret) && !empty($ret)) {
  196. if ($method == 'site/token/index') {
  197. cache_write($cache_key, $ret);
  198. } else {
  199. cache_write($cache_key, $ret, CACHE_EXPIRE_MIDDLE);
  200. }
  201. }
  202. return $ret;
  203. }
  204. function cloud_prepare() {
  205. global $_W;
  206. setting_load();
  207. if (empty($_W['setting']['site']['key']) || empty($_W['setting']['site']['token'])) {
  208. register_shutdown_function('cloud_reset_siteinfo');
  209. return error('-1', '站点注册信息丢失, 系统已帮您重置站点,请刷新重试!如还未解决您可以提交工单解决!');
  210. }
  211. return true;
  212. }
  213. function cloud_build($use_cache = true) {
  214. $pars['method'] = 'application.build4';
  215. $pars['file'] = 'application.build';
  216. $extra = array('use_cache' => $use_cache);
  217. $ret = cloud_api('site/build/index', $pars, $extra);
  218. if (is_error($ret)) {
  219. return $ret;
  220. }
  221. if ($ret['state'] == 'warning') {
  222. $ret['files'] = cloud_client_define();
  223. unset($ret['schemas']);
  224. unset($ret['scripts']);
  225. } else {
  226. $patch_path = sprintf('%s/data/patch/upgrade/%s', IA_ROOT, date('Ymd'));
  227. if (!is_dir($patch_path)) {
  228. mkdirs($patch_path);
  229. }
  230. $files = $files_allowed = array();
  231. if (!empty($ret['files'])) {
  232. foreach ($ret['files'] as $file) {
  233. $entry = IA_ROOT . $file['path'];
  234. if (!is_file($entry) || md5_file($entry) != $file['checksum']) {
  235. $files_allowed[] = $file['path'];
  236. }
  237. $entry = $patch_path . $file['path'];
  238. if (!is_file($entry)) {
  239. $entry = IA_ROOT . $file['path'];
  240. }
  241. if (!is_file($entry) || md5_file($entry) != $file['checksum']) {
  242. $files[] = $file['path'];
  243. }
  244. }
  245. }
  246. $ret['files'] = $files;
  247. if (!empty($ret['files'])) {
  248. cloud_bakup_files($ret['files']);
  249. } else {
  250. if (!empty($files_allowed)) {
  251. foreach ($files_allowed as $file) {
  252. $dir = pathinfo(IA_ROOT . $file, PATHINFO_DIRNAME);
  253. if (!is_dir($dir)) {
  254. mkdirs($dir);
  255. }
  256. file_put_contents(IA_ROOT . $file, file_get_contents($patch_path . $file));
  257. }
  258. rmdirs($patch_path);
  259. }
  260. }
  261. $schemas = array();
  262. if (!empty($ret['schemas'])) {
  263. load()->func('db');
  264. foreach ($ret['schemas'] as $remote) {
  265. $name = substr($remote['tablename'], 4);
  266. $local = db_table_schema(pdo(), $name);
  267. unset($remote['increment']);
  268. unset($local['increment']);
  269. if (empty($local)) {
  270. $schemas[] = $remote;
  271. } else {
  272. $sqls = db_table_fix_sql($local, $remote);
  273. if (!empty($sqls)) {
  274. $schemas[] = $remote;
  275. }
  276. }
  277. }
  278. }
  279. $ret['schemas'] = $schemas;
  280. $file_list = cloud_file_tree(IA_ROOT . '/data/update');
  281. if (!empty($file_list)) {
  282. foreach ($file_list as $file) {
  283. $file_basename = pathinfo($file, PATHINFO_BASENAME);
  284. preg_match('/^update\((\d{12})\-(\d{12})\)\.php$/', $file_basename, $matches);
  285. if (!is_file($file) || (IMS_RELEASE_DATE >= $matches[2] || empty($matches[2]))) {
  286. continue;
  287. }
  288. $ret['scripts'][] = array(
  289. 'message' => '微擎升级',
  290. 'script' => '',
  291. 'release' => $matches[2],
  292. 'fname' => $file_basename,
  293. );
  294. }
  295. }
  296. }
  297. if (IMS_FAMILY != $ret['family']) {
  298. $update_version_success = setting_upgrade_version($ret['family'], IMS_VERSION, IMS_RELEASE_DATE);
  299. if (empty($update_version_success)) {
  300. message('切换版本失败,请修改 /framework/version.inc.php 文件权限为 User 可写或是 777', 'refresh', 'error');
  301. } else {
  302. message('更新系统正在为您自动切换版本', 'refresh');
  303. }
  304. }
  305. $ret['upgrade'] = false;
  306. if (!empty($ret['files']) || !empty($ret['schemas']) || !empty($ret['scripts'])) {
  307. $ret['upgrade'] = true;
  308. }
  309. return $ret;
  310. }
  311. function cloud_check_file() {
  312. $pars['method'] = 'application.build4';
  313. $pars['file'] = 'application.build';
  314. $ret = cloud_api('site/build/index', $pars);
  315. if (is_error($ret)) {
  316. return $ret;
  317. }
  318. if ($ret['state'] == 'warning') {
  319. $ret['files'] = cloud_client_define();
  320. }
  321. return $ret;
  322. }
  323. function cloud_schema() {
  324. $pars['method'] = 'application.schema';
  325. $pars['file'] = 'application.schema';
  326. $ret = cloud_api('site/schema/index', $pars);
  327. if (!is_error($ret)) {
  328. $schemas = array();
  329. if (!empty($ret['schemas'])) {
  330. load()->func('db');
  331. foreach ($ret['schemas'] as $remote) {
  332. $name = substr($remote['tablename'], 4);
  333. $local = db_table_schema(pdo(), $name);
  334. unset($remote['increment']);
  335. unset($local['increment']);
  336. if (empty($local)) {
  337. $schemas[] = $remote;
  338. } else {
  339. $diffs = db_schema_compare($local, $remote);
  340. if (!empty($diffs)) {
  341. $schemas[] = $remote;
  342. }
  343. }
  344. }
  345. }
  346. $ret['schemas'] = $schemas;
  347. }
  348. return $ret;
  349. }
  350. function cloud_download($path, $type = '', $code = '') {
  351. global $_W;
  352. $pars = _cloud_build_params();
  353. $pars['method'] = 'application.shipping';
  354. $pars['path'] = $path;
  355. $pars['type'] = $type;
  356. $pars['gz'] = function_exists('gzcompress') && function_exists('gzuncompress') ? 'true' : 'false';
  357. $pars['download'] = 'true';
  358. $pars['token'] = cloud_build_transtoken();
  359. $pars['code'] = $code;
  360. if (starts_with($_SERVER['HTTP_USER_AGENT'], 'we7')) {
  361. $extra['CURLOPT_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
  362. } else {
  363. $extra = array();
  364. }
  365. $extra['X-We7-Cache'] = cache_random();
  366. $dat = ihttp_request(CLOUD_API_DOMAIN . '/util/shipping/index', $pars, $extra);
  367. if (is_error($dat)) {
  368. WeUtility::logging('cloud-api-error', array('method' => CLOUD_API_DOMAIN . '/util/shipping/index', 'data' => $pars, 'extra' => $extra, 'response' => $dat), true);
  369. return error(-1, '网络存在错误, 请稍后重试。' . $dat['message']);
  370. }
  371. if ($dat['content'] == 'success') {
  372. return true;
  373. }
  374. $content = @json_decode($dat['content'], true);
  375. if (isset($content['error'])) {
  376. WeUtility::logging('cloud-api-error', array('method' => CLOUD_API_DOMAIN . '/util/shipping/index', 'data' => $pars, 'extra' => $extra, 'response' => $dat), true);
  377. return error(1, $content['error']);
  378. }
  379. if (is_error($content)) {
  380. WeUtility::logging('cloud-api-error', array('method' => CLOUD_API_DOMAIN . '/util/shipping/index', 'data' => $pars, 'extra' => $extra, 'response' => $dat), true);
  381. return $content;
  382. } else {
  383. $ret = iunserializer($dat['content']);
  384. $gz = function_exists('gzcompress') && function_exists('gzuncompress');
  385. $file = base64_decode($ret['file']);
  386. if ($gz) {
  387. $file = gzuncompress($file);
  388. }
  389. $_W['setting']['site']['token'] = authcode(cache_load(cache_system_key('cloud_transtoken')), 'DECODE');
  390. $string = (md5($file) . $ret['path'] . $_W['setting']['site']['token']);
  391. if (!empty($_W['setting']['site']['token']) && md5($string) === $ret['sign']) {
  392. $error_file_list = array();
  393. if (!cloud_file_permission_pass($error_file_list)) {
  394. return error(-1, '请修复下列文件读写权限 : ' . implode('; ', $error_file_list));
  395. }
  396. if ($type == 'module' || $type == 'theme') {
  397. $patch_path = IA_ROOT;
  398. } else {
  399. $patch_path = sprintf('%s/data/patch/upgrade/%s', IA_ROOT, date('Ymd'));
  400. }
  401. $path = $patch_path . $ret['path'];
  402. load()->func('file');
  403. @mkdirs(dirname($path));
  404. if (file_put_contents($path, $file)) {
  405. return true;
  406. } else {
  407. return error(-1, '写入失败,请检查是否有写入权限或是否磁盘已满!');
  408. }
  409. }
  410. return error(-1, '与云服务校验失败,更新缓存后重试!');
  411. }
  412. }
  413. function cloud_m_prepare($name, $extra = array()) {
  414. $params = array(
  415. 'method' => 'module.check',
  416. 'module' => $name,
  417. );
  418. if (!empty($extra)) {
  419. $params = array_merge($extra, $params);
  420. }
  421. $ret = cloud_api('module/check', $params);
  422. return $ret;
  423. }
  424. function cloud_m_code($code) {
  425. load()->model('extension');
  426. if (empty($code)) {
  427. return array();
  428. }
  429. $ret = cloud_api('module/code', array('code' => $code));
  430. if (!is_error($ret)) {
  431. $manifest = ext_module_manifest_parse($ret['manifest']);
  432. $modulename = $manifest['application']['identifie'];
  433. $dir = IA_ROOT . '/addons/' . $modulename;
  434. $files = array();
  435. if (!empty($ret['files']['private_file_list'])) {
  436. $ret['files']['common_file_list'] = array_merge($ret['files']['common_file_list'], $ret['files']['private_file_list']);
  437. }
  438. if (!empty($ret['files']['common_file_list'])) {
  439. foreach ($ret['files']['common_file_list'] as $file) {
  440. if ($file['path'] == '/map.json') {
  441. continue;
  442. }
  443. if (empty(safe_gpc_path($file['path']))) {
  444. $messy_code_file .= '<br>/' . $modulename . $file['path'];
  445. } else {
  446. $entry = $dir . $file['path'];
  447. if (!is_file($entry) || md5_file($entry) != $file['checksum']) {
  448. $files[] = '/' . $modulename . $file['path'];
  449. }
  450. }
  451. }
  452. }
  453. $ret['files'] = $files;
  454. if (!empty($messy_code_file) && !igetcookie($code . '_install')) {
  455. return error(-2, '包含命名不规范文件,请联系开发者处理或忽略异常文件点击“确定”后再次输入测试码以继续安装。<br>文件如下:' . $messy_code_file);
  456. }
  457. $schemas = array();
  458. if (!empty($ret['schemas'])) {
  459. load()->func('db');
  460. foreach ($ret['schemas'] as $remote) {
  461. $name = substr($remote['tablename'], 4);
  462. $local = db_table_schema(pdo(), $name);
  463. unset($remote['increment']);
  464. unset($local['increment']);
  465. if (empty($local)) {
  466. $schemas[] = $remote;
  467. } else {
  468. $diffs = db_table_fix_sql($local, $remote);
  469. if (!empty($diffs)) {
  470. $schemas[] = $remote;
  471. }
  472. }
  473. }
  474. }
  475. $ret['type'] = 'module';
  476. $ret['schemas'] = $schemas;
  477. $module = table('modules')->getByName($modulename);
  478. if (empty($module)) {
  479. $ret['install'] = STATUS_ON;
  480. } else {
  481. $ret['upgrade'] = STATUS_ON;
  482. }
  483. }
  484. return $ret;
  485. }
  486. function cloud_m_code_query($use_cache = true) {
  487. return cloud_api('module/code/query', array(), array('use_cache' => $use_cache));
  488. }
  489. function cloud_m_code_generate($data) {
  490. $result = cloud_api('module/code/generate', array('module_name' => $data['module_name'], 'module_version' => $data['module_version']));
  491. if (is_error($result)) {
  492. return $result['message'];
  493. }
  494. return $result['code'];
  495. }
  496. function cloud_m_code_available($code = array()) {
  497. return cloud_api('module/code/available', array('code' => $code));
  498. }
  499. function cloud_m_build($modulename, $type = 'install') {
  500. $type = in_array($type, array('uninstall', 'upgrade', 'install')) ? $type : 'install';
  501. if (empty($modulename)) {
  502. return array();
  503. }
  504. $module_info = cloud_m_info($modulename);
  505. if (is_error($module_info)) {
  506. return $module_info;
  507. }
  508. $pars['module'] = $modulename;
  509. $pars['type'] = $type;
  510. $pars['module_version'] = $module_info['version']['version'];
  511. $pars['file'] = 'module.build';
  512. $ret = cloud_api('module/build', $pars);
  513. if (!is_error($ret)) {
  514. $dir = IA_ROOT . '/addons/' . $modulename;
  515. $files = array();
  516. $messy_code_file = '';
  517. if (!empty($ret['files'])) {
  518. foreach ($ret['files'] as $file) {
  519. if ($file['path'] == '/map.json') {
  520. continue;
  521. }
  522. if (empty(safe_gpc_path($file['path']))) {
  523. $messy_code_file .= '<br>/' . $modulename . $file['path'];
  524. } else {
  525. $entry = $dir . $file['path'];
  526. if (!is_file($entry) || md5_file($entry) != $file['checksum']) {
  527. $files[] = '/' . $modulename . $file['path'];
  528. }
  529. }
  530. }
  531. }
  532. $ret['files'] = $files;
  533. if (!empty($messy_code_file) && !igetcookie($modulename . '_install')) {
  534. return error(-2, '包含命名不规范文件,请联系开发者处理或忽略异常文件点击“确定”后再次点击“去安装”以继续安装。<br>文件如下:' . $messy_code_file);
  535. }
  536. $schemas = array();
  537. if (!empty($ret['schemas'])) {
  538. load()->func('db');
  539. foreach ($ret['schemas'] as $remote) {
  540. $name = substr($remote['tablename'], 4);
  541. $local = db_table_schema(pdo(), $name);
  542. unset($remote['increment']);
  543. unset($local['increment']);
  544. if (empty($local)) {
  545. $schemas[] = $remote;
  546. } else {
  547. $diffs = db_table_fix_sql($local, $remote);
  548. if (!empty($diffs)) {
  549. $schemas[] = $remote;
  550. }
  551. }
  552. }
  553. }
  554. $ret['type'] = 'module';
  555. $ret['schemas'] = $schemas;
  556. $module = table('modules')->getByName($modulename);
  557. if (empty($module)) {
  558. $ret['install'] = STATUS_ON;
  559. } else {
  560. $ret['upgrade'] = STATUS_ON;
  561. }
  562. }
  563. return $ret;
  564. }
  565. function cloud_m_query($module = array(), $page = 1, $use_cache = true) {
  566. $pars['method'] = 'module.query';
  567. if (empty($module)) {
  568. $module = cloud_extra_module();
  569. }
  570. if (!is_array($module)) {
  571. $module = array($module);
  572. }
  573. $pars['page'] = max(1, intval($page));
  574. $pars['module'] = base64_encode(iserializer($module));
  575. $ret = cloud_api('module/query', $pars, array('use_cache' => $use_cache));
  576. if (isset($ret['error'])) {
  577. return error(1, $ret['error']);
  578. }
  579. if (!is_error($ret)) {
  580. $pirate_apps = empty($ret['pirate_apps']) ? array() : $ret['pirate_apps'];
  581. unset($ret['pirate_apps']);
  582. $support_names = array('app', 'wxapp', 'webapp', 'system_welcome', 'android', 'ios', 'aliapp', 'baiduapp', 'toutiaoapp');
  583. $record_module = array();
  584. foreach ($ret['data'] as $modulename => &$info) {
  585. if (!empty($info['name'])) {
  586. $record_module[] = $info['name'];
  587. }
  588. if (empty($info['site_branch'])) {
  589. continue;
  590. }
  591. foreach ($support_names as $support) {
  592. if (is_array($info['site_branch']['bought']) && in_array($support, $info['site_branch']['bought']) && !empty($info['site_branch']["{$support}_support"]) && $info['site_branch']["{$support}_support"] == 2) {
  593. $info['site_branch']["{$support}_support"] = 2;
  594. } else {
  595. $info['site_branch']["{$support}_support"] = 1;
  596. }
  597. }
  598. }
  599. $ret['pirate_apps'] = $pirate_apps;
  600. table('modules')->where(array('name IN' => $record_module))->fill(array('cloud_record' => STATUS_ON))->save();
  601. }
  602. return $ret;
  603. }
  604. function cloud_m_info($name) {
  605. $pars['method'] = 'module.info';
  606. $pars['module'] = $name;
  607. $ret = cloud_api('module/info', $pars);
  608. return $ret;
  609. }
  610. function cloud_m_upgradeinfo($modulename) {
  611. load()->model('module');
  612. $module = module_fetch($modulename);
  613. $pars['method'] = 'module.info';
  614. $pars['module'] = $modulename;
  615. $pars['curversion'] = $module['version'];
  616. $pars['isupgrade'] = 1;
  617. $ret = cloud_api('module/info', $pars);
  618. if (empty($ret)) {
  619. return array();
  620. }
  621. if (is_error($ret)) {
  622. return $ret;
  623. }
  624. if (version_compare($ret['version']['version'], $module['version'], '>')) {
  625. $ret['upgrade'] = true;
  626. }
  627. $ret['site_branch'] = $ret['branches'][$ret['version']['branch_id']];
  628. $ret['from'] = 'cloud';
  629. foreach ($ret['branches'] as &$branch) {
  630. if ($branch['displayorder'] > $ret['site_branch']['displayorder'] || ($branch['displayorder'] == $ret['site_branch']['displayorder'] && $ret['site_branch']['id'] < intval($branch['id']))) {
  631. $ret['new_branch'] = true;
  632. }
  633. $branch['id'] = intval($branch['id']);
  634. $branch['version']['description'] = preg_replace('/\n/', '<br/>', htmlspecialchars_decode($branch['version']['description']));
  635. $branch['displayorder'] = intval($branch['displayorder']);
  636. $branch['day'] = intval(date('d', $branch['version']['createtime']));
  637. $branch['month'] = date('Y.m', $branch['version']['createtime']);
  638. $branch['hour'] = date('H:i', $branch['version']['createtime']);
  639. }
  640. unset($branch);
  641. return $ret;
  642. }
  643. function cloud_t_prepare($name, $extra = array()) {
  644. $pars = array(
  645. 'method' => 'theme.check',
  646. 'theme' => $name,
  647. );
  648. if (!empty($extra)) {
  649. $pars = array_merge($extra, $pars);
  650. }
  651. $dat = cloud_api('theme/check', $pars);
  652. return $dat;
  653. }
  654. function cloud_t_query() {
  655. $pars['method'] = 'theme.query';
  656. $pars['theme'] = cloud_extra_theme();
  657. $ret = cloud_api('theme/query', $pars);
  658. return $ret;
  659. }
  660. function cloud_t_info($module_name) {
  661. $pars['method'] = 'theme.info';
  662. $pars['theme'] = $module_name;
  663. $ret = cloud_api('theme/info', $pars);
  664. return $ret;
  665. }
  666. function cloud_t_build($module_name) {
  667. if (empty($module_name)) {
  668. return array();
  669. }
  670. $theme = table('modules')->getTemplateByName(trim($module_name));
  671. $pars['method'] = 'theme.build';
  672. $pars['theme'] = $module_name;
  673. if (!empty($theme)) {
  674. $pars['themeversion'] = $theme['version'];
  675. }
  676. $ret = cloud_api('theme/build', $pars);
  677. if (!is_error($ret)) {
  678. $dir = IA_ROOT . '/app/themes/' . $module_name;
  679. $files = array();
  680. if (!empty($ret['files'])) {
  681. foreach ($ret['files'] as $file) {
  682. if ($file['path'] == '/map.json') {
  683. continue;
  684. }
  685. $entry = $dir . $file['path'];
  686. if (!is_file($entry) || md5_file($entry) != $file['checksum']) {
  687. $files[] = '/' . $module_name . $file['path'];
  688. }
  689. }
  690. }
  691. $ret['files'] = $files;
  692. if (!empty($theme) && version_compare($theme['version'], $ret['version']) == -1) {
  693. $ret['upgrade'] = true;
  694. } else {
  695. $ret['upgrade'] = false;
  696. }
  697. $ret['type'] = 'theme';
  698. if (empty($theme)) {
  699. $ret['install'] = 1;
  700. }
  701. }
  702. return $ret;
  703. }
  704. function cloud_t_upgradeinfo($module_name) {
  705. if (empty($module_name)) {
  706. return array();
  707. }
  708. $theme = table('modules')->getTemplateByName(trim($module_name));
  709. if (empty($theme)) {
  710. return array();
  711. }
  712. return cloud_api('theme/upgrade', array(
  713. 'method' => 'theme.upgrade',
  714. 'theme' => $theme['name'],
  715. 'version' => $theme['version'],
  716. 'isupgrade' => 1,
  717. ));
  718. }
  719. function cloud_sms_send($mobile, $content, $postdata = array(), $custom_sign = '', $use_system_balance = false) {
  720. global $_W;
  721. if (!preg_match('/^1\d{10}$/', $mobile) || empty($content)) {
  722. return error(1, '发送短信失败, 原因: 手机号错误或内容为空.');
  723. }
  724. $sms_send_info = pdo_get('uni_verifycode', array('receiver' => $mobile));
  725. if (!empty($sms_send_info) && 10 < $sms_send_info['total'] && 7200 >= TIMESTAMP - $sms_send_info['createtime']) {
  726. return error(-1, '同一手机号两小时内请求发送验证码超出10次');
  727. }
  728. $uniacid = empty($use_system_balance) ? $_W['uniacid'] : 0;
  729. if (empty($uniacid)) {
  730. $setting_sms_blance = setting_load('system_sms_balance');
  731. $balance = !empty($setting_sms_blance['system_sms_balance']) ? $setting_sms_blance['system_sms_balance'] : 0;
  732. $setting_sms_sign = setting_load('site_sms_sign');
  733. $setting_sms_sign = !empty($setting_sms_sign['site_sms_sign']) ? $setting_sms_sign['site_sms_sign'] : array();
  734. $sign = !empty($setting_sms_sign['system_sms_sign']) ? $setting_sms_sign['system_sms_sign'] : '';
  735. } else {
  736. $row = pdo_get('uni_settings', array('uniacid' => $uniacid), array('notify'));
  737. $row['notify'] = @iunserializer($row['notify']);
  738. $config = empty($row['notify']['sms']) ? array() : $row['notify']['sms'];
  739. $balance = empty($config['balance']) ? 0 : intval($config['balance']);
  740. $sign = empty($custom_sign) && !empty($config['signature']) ? $config['signature'] : $custom_sign;
  741. $account_name = empty($_W['account']['type_name']) ? '' : $_W['account']['type_name'];
  742. $account_name .= empty($_W['account']['name']) ? '' : " [{$_W['account']['name']}] ";
  743. }
  744. if (empty($sign) || $sign == 'null') {
  745. $sign = '微擎';
  746. }
  747. $sms_info = cloud_sms_info();
  748. if ($balance < 1 || empty($sms_info['sms_count'])) {
  749. return error(-1, '短信不足');
  750. }
  751. $pars = _cloud_build_params(false);
  752. $pars['method'] = 'sms.send';
  753. $pars['mobile'] = $mobile;
  754. $pars['uniacid'] = $uniacid;
  755. $pars['account_name'] = empty($account_name) ? '当前公众号' : $account_name;
  756. $pars['balance'] = $balance;
  757. $pars['sign'] = $sign;
  758. if (!empty($postdata)) {
  759. $pars['content'] = $content;
  760. $pars['postdata'] = $postdata;
  761. } else {
  762. $pars['content'] = "{$content} 【{$sign}】";
  763. }
  764. $extra = array();
  765. if (starts_with($_SERVER['HTTP_USER_AGENT'], 'we7')) {
  766. $extra['CURLOPT_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
  767. }
  768. $response = cloud_request(CLOUD_API_DOMAIN . '/sms/send/index', $pars, $extra);
  769. if (is_error($response)) {
  770. return error($response['errno'], '短信发送失败, 原因:' . $response['message']);
  771. }
  772. $result = json_decode($response['content'], true);
  773. if (is_error($result)) {
  774. return error($result['errno'], $result['message']);
  775. }
  776. if (!empty($result['error'])) {
  777. return error(-1, $result['error']);
  778. }
  779. if (intval($result['errno']) != -1) {
  780. if (!empty($uniacid)) {
  781. $row['notify']['sms']['balance'] = $row['notify']['sms']['balance'] - 1;
  782. if ($row['notify']['sms']['balance'] < 0) {
  783. $row['notify']['sms']['balance'] = 0;
  784. }
  785. pdo_update('uni_settings', array('notify' => iserializer($row['notify'])), array('uniacid' => $uniacid));
  786. uni_setting_save('notify', $row['notify']);
  787. } else {
  788. $balance -= 1;
  789. if ($balance < 0) {
  790. $balance = 0;
  791. }
  792. setting_save($balance, 'system_sms_balance');
  793. $sms_info['sms_count'] = $sms_info['sms_count'] - 1;
  794. if ($sms_info['sms_count'] < 0) {
  795. $sms_info['sms_count'] = 0;
  796. }
  797. setting_save($sms_info, 'sms.info');
  798. }
  799. }
  800. return true;
  801. }
  802. function cloud_sms_info() {
  803. return cloud_api('sms/info');
  804. }
  805. function cloud_sms_sign($page = 1, $start_time = 0, $end_time = 0, $status_audit = 0, $status_order = 0) {
  806. $data = array(
  807. 'page' => max(1, intval($page))
  808. );
  809. if ($start_time) {
  810. $data['start_time'] = $start_time;
  811. }
  812. if ($end_time) {
  813. $data['end_time'] = $end_time;
  814. }
  815. if ($status_audit) {
  816. $data['status_audit'] = $status_audit;
  817. }
  818. if ($status_order) {
  819. $data['status_order'] = $status_order;
  820. }
  821. return cloud_api('sms/sign', $data);
  822. }
  823. function cloud_sms_log($mobile = 0, $time = array(), $page = 1, $page_size = 10, $status = -1) {
  824. $time = !empty($time) ? $time : array(strtotime('-7 days'), time());
  825. return cloud_api('sms/log', array(
  826. 'mobile' => $mobile,
  827. 'time' => $time,
  828. 'page' => $page,
  829. 'page_size' => $page_size,
  830. 'status' => $status
  831. ), array('use_cache' => false));
  832. }
  833. function cloud_sms_trade($page = 1, $start_time = 0, $end_time = 0, $status_order = 0) {
  834. $data = array(
  835. 'page' => max(1, intval($page))
  836. );
  837. if ($start_time) {
  838. $data['start_time'] = $start_time;
  839. }
  840. if ($end_time) {
  841. $data['end_time'] = $end_time;
  842. }
  843. if ($status_order) {
  844. $data['status_order'] = $status_order;
  845. }
  846. if (empty($data['start_time']) && empty($data['end_time'])) {
  847. $data['start_time'] = strtotime('-1 year');
  848. $data['end_time'] = time();
  849. }
  850. $data['time'] = array($data['start_time'], $data['end_time']);
  851. return cloud_api('sms/trade', $data);
  852. }
  853. function cloud_sms_edit($sign) {
  854. return cloud_api('sms/re-audit-sign', array('sign_id' => $sign['sign_id'], 'sms_sign' => $sign['sign_content']));
  855. }
  856. function cloud_sms_count_remained() {
  857. $cache_key = cache_system_key('cloud_api', array('method' => md5('cloud_sms_count_remained')));
  858. $cache = cache_load($cache_key);
  859. if (!empty($cache) && !empty($cache['expire']) && $cache['expire'] > TIMESTAMP) {
  860. return $cache['cloud_sms_count_remained'];
  861. }
  862. $sms_info = cloud_sms_info();
  863. if (is_error($sms_info)) {
  864. return $sms_info;
  865. }
  866. $sms_count = $sms_info['sms_count'];
  867. $sms_accounts = table('uni_settings')->select(array('uniacid', 'notify'))->where(array('notify LIKE' => '%sms%'))->getall();
  868. $setting_sms_blance = setting_load('system_sms_balance');
  869. $system_sms_balance = !empty($setting_sms_blance['system_sms_balance']) ? $setting_sms_blance['system_sms_balance'] : 0;
  870. $sms_count -= $system_sms_balance;
  871. if (empty($sms_accounts)) {
  872. return $sms_count;
  873. }
  874. foreach ($sms_accounts as $sms_account) {
  875. $notify = iunserializer($sms_account['notify']);
  876. $sms_count -= $notify['sms']['balance'];
  877. }
  878. $sms_count = max(0, $sms_count);
  879. $cache_data = array(
  880. 'cloud_sms_count_remained' => $sms_count
  881. );
  882. cache_write($cache_key, $cache_data, CACHE_EXPIRE_MIDDLE);
  883. return $sms_count;
  884. }
  885. function cloud_extra_module() {
  886. load()->model('module');
  887. $result = array();
  888. $cloud = table('modules_cloud')->getUninstallModule(MODULE_CLOUD_UNINSTALL);
  889. if (empty($cloud)) {
  890. return $result;
  891. }
  892. $module_support_type = array_keys(module_support_type());
  893. $installed = table('modules')->getInstalled();
  894. $recycle = table('modules_recycle')->where('type', 2)->getall('name');
  895. foreach ($installed as $install_module) {
  896. if ($install_module['cloud_record']) {
  897. continue;
  898. }
  899. $result[$install_module['name']] = array(
  900. 'name' => $install_module['name'],
  901. 'version' => $install_module['version'],
  902. );
  903. $all_uninstall = true;
  904. foreach ($module_support_type as $support) {
  905. $type = str_replace('_support', '', $support);
  906. if ($install_module[$support] == 2) {
  907. $all_uninstall = false;
  908. $result[$install_module['name']]['support'][$type]['is_install'] = 2;
  909. }
  910. }
  911. if ($all_uninstall) {
  912. unset($result[$install_module['name']]);
  913. }
  914. }
  915. foreach ($recycle as $recycle_module) {
  916. if (empty($result[$recycle_module['name']])) {
  917. $result[$recycle_module['name']] = array(
  918. 'name' => $recycle_module['name'],
  919. );
  920. }
  921. $in_recycle = false;
  922. foreach ($module_support_type as $support) {
  923. $type = str_replace('_support', '', $support);
  924. if ($recycle_module[$support]) {
  925. $in_recycle = true;
  926. $result[$recycle_module['name']]['support'][$type] = array(
  927. 'is_recycle' => 2
  928. );
  929. }
  930. }
  931. if (!$in_recycle) {
  932. unset($result[$recycle_module['name']]);
  933. }
  934. }
  935. foreach ($cloud as $cloud_module) {
  936. if (empty($result[$cloud_module['name']])) {
  937. $result[$cloud_module['name']] = array(
  938. 'name' => $cloud_module['name'],
  939. 'version' => $cloud_module['version'],
  940. );
  941. }
  942. $in_cloud = false;
  943. foreach ($module_support_type as $support) {
  944. $type = str_replace('_support', '', $support);
  945. if ($cloud_module[$support] == 2) {
  946. $in_cloud = true;
  947. $result[$cloud_module['name']]['support'][$type] = array(
  948. 'is_uninstall' => 2
  949. );
  950. }
  951. }
  952. if (!$in_cloud) {
  953. unset($result[$cloud_module['name']]);
  954. }
  955. }
  956. return $result;
  957. }
  958. function cloud_extra_theme() {
  959. $themes = pdo_getall('modules', array('application_type' => APPLICATION_TYPE_TEMPLATES, 'name !=' => 'default'), 'name', 'name');
  960. if (!empty($themes)) {
  961. return base64_encode(iserializer(array_keys($themes)));
  962. } else {
  963. return '';
  964. }
  965. }
  966. function cloud_module_setting($acid, $module) {
  967. $pars = array(
  968. 'acid' => $acid,
  969. 'module_name' => $module['name'],
  970. 'module_version' => $module['version'],
  971. );
  972. return cloud_api('module/setting/index', $pars);
  973. }
  974. function cloud_module_setting_save($acid, $module_name, $setting) {
  975. $pars = array(
  976. 'acid' => $acid,
  977. 'module_name' => $module_name,
  978. 'setting' => $setting,
  979. );
  980. return cloud_api('module/setting/save', $pars, array('use_cache' => false));
  981. }
  982. function cloud_module_list($title, $support_type, $page = 1, $per_page = 20) {
  983. $pars = array(
  984. 'title' => $title,
  985. 'support_type' => $support_type,
  986. 'page' => $page,
  987. 'per_page' => $per_page,
  988. );
  989. return cloud_api('module/list', $pars);
  990. }
  991. function cloud_site_info() {
  992. return cloud_api('site/info');
  993. }
  994. function cloud_reset_siteinfo() {
  995. global $_W;
  996. return cloud_api('site/register/profile', array('url' => $_W['siteroot']));
  997. }
  998. function cloud_wxapp_info($moduleinfo) {
  999. return cloud_api('wxapp/info', $moduleinfo);
  1000. }
  1001. function cloud_wxapp_login_qrcode() {
  1002. return cloud_api('wxapp/login/qr-code', array(), array('use_cache' => false));
  1003. }
  1004. function cloud_wxapp_login_qrscan($uuid) {
  1005. return cloud_api('wxapp/login/qr-scan', $uuid);
  1006. }
  1007. function cloud_wxapp_publish($data) {
  1008. return cloud_api('wxapp/publish', $data);
  1009. }
  1010. function cloud_miniapp_get_package($data) {
  1011. return cloud_api('wxapp/publish/download', $data);
  1012. }
  1013. function cloud_auth_url($forward, $data = array()) {
  1014. global $_W;
  1015. if (!empty($_W['setting']['site']['url']) && !strexists($_W['siteroot'], $_W['setting']['site']['url'])) {
  1016. $url = $_W['setting']['site']['url'];
  1017. } else {
  1018. $url = rtrim($_W['siteroot'], '/');
  1019. }
  1020. $auth = array();
  1021. $auth['key'] = '';
  1022. $auth['password'] = '';
  1023. $auth['url'] = $url;
  1024. $auth['referrer'] = intval($_W['config']['setting']['referrer']);
  1025. $auth['version'] = IMS_VERSION;
  1026. $auth['forward'] = $forward;
  1027. $auth['family'] = IMS_FAMILY;
  1028. if (!empty($_W['setting']['site']['key']) && !empty($_W['setting']['site']['token'])) {
  1029. $auth['key'] = $_W['setting']['site']['key'];
  1030. $auth['password'] = md5($_W['setting']['site']['key'] . $_W['setting']['site']['token']);
  1031. }
  1032. if ($data && is_array($data)) {
  1033. $auth = array_merge($auth, $data);
  1034. }
  1035. $query = base64_encode(json_encode($auth));
  1036. $auth_url = 'https://s.w7.cc/index.php?c=auth&a=passport&__auth=' . $query;
  1037. return $auth_url;
  1038. }
  1039. function cloud_module_setting_prepare($module, $binding) {
  1040. global $_W;
  1041. $auth = _cloud_build_params();
  1042. $auth['arguments'] = array(
  1043. 'binding' => $binding,
  1044. 'acid' => $_W['uniacid'],
  1045. 'type' => 'module',
  1046. 'module' => $module,
  1047. );
  1048. $iframe_auth_url = cloud_auth_url('module', $auth);
  1049. return $iframe_auth_url;
  1050. }
  1051. function cloud_resource_to_local($uniacid, $type, $url) {
  1052. global $_W;
  1053. load()->func('file');
  1054. $setting = $_W['setting']['upload'][$type];
  1055. if (substr($url, 0, 2) == '//') {
  1056. $url = 'http:' . $url;
  1057. }
  1058. if (!file_is_image($url)) {
  1059. return error(1, '远程图片后缀非法,请重新上传');
  1060. }
  1061. $pathinfo = pathinfo($url);
  1062. $extension = $pathinfo['extension'];
  1063. if ($uniacid == 0) {
  1064. $setting['folder'] = "{$type}s/global/" . date('Y/m/');
  1065. } else {
  1066. $setting['folder'] = "{$type}s/{$uniacid}/" . date('Y/m/');
  1067. }
  1068. $originname = pathinfo($url, PATHINFO_BASENAME);
  1069. $filename = file_random_name(ATTACHMENT_ROOT . '/' . $setting['folder'], $extension);
  1070. $pathname = $setting['folder'] . $filename;
  1071. $fullname = ATTACHMENT_ROOT . $pathname;
  1072. mkdirs(dirname($fullname));
  1073. load()->func('communication');
  1074. $response = ihttp_get($url);
  1075. if (is_error($response)) {
  1076. return error(1, $response['message']);
  1077. }
  1078. if (file_put_contents($fullname, $response['content']) == false) {
  1079. return error(1, '提取文件失败');
  1080. }
  1081. if (!empty($_W['setting']['remote']['type'])) {
  1082. $remotestatus = file_remote_upload($pathname);
  1083. if (is_error($remotestatus)) {
  1084. return error(1, '远程附件上传失败,请检查配置并重新上传');
  1085. } else {
  1086. file_delete($pathname);
  1087. }
  1088. }
  1089. $data = array(
  1090. 'uniacid' => $uniacid,
  1091. 'uid' => intval($_W['uid']),
  1092. 'filename' => $originname,
  1093. 'attachment' => $pathname,
  1094. 'type' => $type == 'image' ? 1 : 2,
  1095. 'createtime' => TIMESTAMP,
  1096. );
  1097. pdo_insert('core_attachment', $data);
  1098. $data['url'] = tomedia($pathname);
  1099. $data['id'] = pdo_insertid();
  1100. return $data;
  1101. }
  1102. function cloud_bakup_files($files) {
  1103. global $_W;
  1104. if (empty($files)) {
  1105. return false;
  1106. }
  1107. $map = json_encode($files);
  1108. $hash = md5($map . $_W['config']['setting']['authkey']);
  1109. if ($handle = opendir(IA_ROOT . '/data/patch/backup/' . date('Ymd'))) {
  1110. while (false !== ($patchpath = readdir($handle))) {
  1111. if ($patchpath != '.' && $patchpath != '..') {
  1112. if (strexists($patchpath, $hash)) {
  1113. return false;
  1114. }
  1115. }
  1116. }
  1117. }
  1118. $path = IA_ROOT . '/data/patch/backup/' . date('Ymd') . '/' . date('Hi') . '_' . $hash;
  1119. load()->func('file');
  1120. if (!is_dir($path) && mkdirs($path)) {
  1121. foreach ($files as $file) {
  1122. if (file_exists(IA_ROOT . $file)) {
  1123. mkdirs($path . '/' . dirname($file));
  1124. file_put_contents($path . '/' . $file, file_get_contents(IA_ROOT . $file));
  1125. }
  1126. }
  1127. file_put_contents($path . '/' . 'map.json', $map);
  1128. }
  1129. return false;
  1130. }
  1131. function cloud_build_transtoken() {
  1132. $pars['method'] = 'application.token';
  1133. $pars['file'] = 'application.build';
  1134. $ret = cloud_api('site/token/index', $pars);
  1135. if (!empty($ret['token'])) {
  1136. cache_write(cache_system_key('cloud_transtoken'), authcode($ret['token'], 'ENCODE'));
  1137. return $ret['token'];
  1138. }
  1139. return '';
  1140. }
  1141. function cloud_build_schemas($schemas) {
  1142. $database = array();
  1143. if (empty($schemas) || !is_array($schemas)) {
  1144. return $database;
  1145. }
  1146. foreach ($schemas as $remote) {
  1147. $row = array();
  1148. $row['tablename'] = $remote['tablename'];
  1149. $name = substr($remote['tablename'], 4);
  1150. $local = db_table_schema(pdo(), $name);
  1151. unset($remote['increment']);
  1152. unset($local['increment']);
  1153. if (empty($local)) {
  1154. $row['new'] = true;
  1155. } else {
  1156. $row['new'] = false;
  1157. $row['fields'] = array();
  1158. $row['indexes'] = array();
  1159. $diffs = db_schema_compare($local, $remote);
  1160. if (!empty($diffs['fields']['less'])) {
  1161. $row['fields'] = array_merge($row['fields'], $diffs['fields']['less']);
  1162. }
  1163. if (!empty($diffs['fields']['diff'])) {
  1164. $row['fields'] = array_merge($row['fields'], $diffs['fields']['diff']);
  1165. }
  1166. if (!empty($diffs['indexes']['less'])) {
  1167. $row['indexes'] = array_merge($row['indexes'], $diffs['indexes']['less']);
  1168. }
  1169. if (!empty($diffs['indexes']['diff'])) {
  1170. $row['indexes'] = array_merge($row['indexes'], $diffs['indexes']['diff']);
  1171. }
  1172. $row['fields'] = implode(' ', $row['fields']);
  1173. $row['indexes'] = implode(' ', $row['indexes']);
  1174. }
  1175. $database[] = $row;
  1176. }
  1177. return $database;
  1178. }
  1179. function cloud_file_permission_pass(&$error_file_list = array()) {
  1180. $cache_key = cache_system_key('cloud_file_permission_pass');
  1181. $cache = cache_load($cache_key);
  1182. if ($cache) {
  1183. return true;
  1184. }
  1185. $check_path = array(
  1186. '/api',
  1187. '/app/common',
  1188. '/app/resource',
  1189. '/app/source',
  1190. '/app/themes/default',
  1191. '/web/common',
  1192. '/web/resource',
  1193. '/web/source',
  1194. '/web/themes/default',
  1195. '/web/themes/black',
  1196. '/web/themes/classical',
  1197. '/web/themes/2.0',
  1198. '/framework/builtin',
  1199. '/framework/class',
  1200. '/framework/model',
  1201. '/framework/function',
  1202. '/framework/table',
  1203. '/framework/library',
  1204. '/payment',
  1205. );
  1206. $check_file = array(
  1207. '/web/index.php',
  1208. '/framework/bootstrap.inc.php',
  1209. '/framework/version.inc.php',
  1210. '/framework/const.inc.php',
  1211. );
  1212. $sub_paths = array();
  1213. foreach ($check_path as $path) {
  1214. $file_list = cloud_file_tree(IA_ROOT . $path);
  1215. if (!empty($file_list)) {
  1216. foreach ($file_list as $file) {
  1217. if (is_file($file)) {
  1218. $sub_path = pathinfo($file, PATHINFO_DIRNAME);
  1219. if (empty($sub_paths[$sub_path])) {
  1220. if (!cloud_path_is_writable($sub_path)) {
  1221. $error_file_list[] = str_replace(IA_ROOT, '', $sub_path);
  1222. }
  1223. $sub_paths[$sub_path] = $sub_path;
  1224. }
  1225. }
  1226. if (!is_writable($file)) {
  1227. $error_file_list[] = str_replace(IA_ROOT, '', $file);
  1228. }
  1229. }
  1230. }
  1231. }
  1232. foreach ($check_file as $file) {
  1233. if (!is_writable(IA_ROOT . $file)) {
  1234. $error_file_list[] = str_replace(IA_ROOT, '', $file);
  1235. }
  1236. }
  1237. if (empty($error_file_list)) {
  1238. cache_write($cache_key, true, 600);
  1239. return true;
  1240. }
  1241. return false;
  1242. }
  1243. function cloud_file_tree($path, $include = array()) {
  1244. $files = array();
  1245. if (!empty($include)) {
  1246. $ds = glob($path . '/{' . implode(',', $include) . '}', GLOB_BRACE);
  1247. } else {
  1248. $ds = glob($path . '/*');
  1249. }
  1250. if (is_array($ds)) {
  1251. foreach ($ds as $entry) {
  1252. if (is_file($entry)) {
  1253. $files[] = $entry;
  1254. }
  1255. if (is_dir($entry)) {
  1256. $rs = cloud_file_tree($entry);
  1257. foreach ($rs as $f) {
  1258. $files[] = $f;
  1259. }
  1260. }
  1261. }
  1262. }
  1263. return $files;
  1264. }
  1265. function cloud_path_is_writable($dir) {
  1266. $writeable = false;
  1267. if (!is_dir($dir)) {
  1268. @mkdir($dir, 0755);
  1269. }
  1270. if (is_dir($dir)) {
  1271. if ($fp = fopen("$dir/test.txt", 'w')) {
  1272. fclose($fp);
  1273. unlink("$dir/test.txt");
  1274. $writeable = true;
  1275. } else {
  1276. $writeable = false;
  1277. }
  1278. }
  1279. return $writeable;
  1280. }
  1281. function cloud_get_store_notice() {
  1282. return cloud_api('we7/site/notify/system');
  1283. }
  1284. function cloud_v_to_xs($url) {
  1285. if (empty($url)) {
  1286. return false;
  1287. }
  1288. $pars = _cloud_build_params();
  1289. $pars['method'] = 'module.query';
  1290. $pars['url'] = urlencode($url);
  1291. cloud_request(CLOUD_API_DOMAIN . '/site/pirate/index', $pars);
  1292. return true;
  1293. }
  1294. function cloud_w7_request_token($js_secret, $use_cache = true) {
  1295. global $_W;
  1296. if (empty($js_secret) || empty($_W['setting']['site']) || empty($_W['setting']['site']['key'])) {
  1297. return error(-1, '获取站点信息失败!');
  1298. }
  1299. $cache_key = cache_system_key('cloud_w7_request_token');
  1300. if ($use_cache) {
  1301. $cache = cache_load($cache_key);
  1302. if ($cache) {
  1303. return $cache;
  1304. }
  1305. }
  1306. $js_token = authcode($js_secret, 'ENCODE', $_W['setting']['site']['key']);
  1307. $data = array('js_token' => $js_token);
  1308. $ret = cloud_api('site/accesstoken/with-js-token', $data);
  1309. if (is_error($ret)) {
  1310. return $ret;
  1311. }
  1312. cache_write($cache_key, $ret['access_token'], $ret['expire_time'] - TIMESTAMP);
  1313. return $ret['access_token'];
  1314. }
  1315. function cloud_check_mobile($data) {
  1316. return cloud_api('we7/oauth/user-bind/mobile-bind-info', $data);
  1317. }
  1318. function cloud_unbind_user($uid, $openid = '') {
  1319. return cloud_api('we7/oauth/user-bind/unbind', array('out_user_id' => $uid, 'out_openid' => $openid));
  1320. }
  1321. function cloud_bind_user_info($uid) {
  1322. return cloud_api('we7/oauth/user-bind/info', array('out_user_id' => $uid));
  1323. }
  1324. function cloud_oauth_token($code) {
  1325. return cloud_api('site/oauth/access-token/code', array('code' => $code));
  1326. }
  1327. function cloud_oauth_user($token) {
  1328. return cloud_api('site/oauth/user/info', array('access_token' => $token), array('use_cache' => false));
  1329. }
  1330. function cloud_oauth_login_url($redirect) {
  1331. $result = cloud_api('site/oauth/login-url/index', array('redirect' => $redirect));
  1332. if (empty($result['url'])) {
  1333. return error(-1, '获取授权登录url失败,请联系管理员处理!');
  1334. }
  1335. return $result['url'];
  1336. }
  1337. function cloud_oauth_register_url($data) {
  1338. return cloud_api('site/oauth/register-url/index', $data);
  1339. }
  1340. function cloud_bind_user_token($data) {
  1341. return cloud_api('we7/oauth/user-bind/complete-with-accesstoken', $data);
  1342. }
  1343. function cloud_console_index_url($data) {
  1344. return cloud_api('we7/site/console/index-url', $data);
  1345. }
  1346. function cloud_console_invite_url($redirect = '', $state = array()) {
  1347. return cloud_api('we7/site/console/share-url', array('role_identify' => ACCOUNT_MANAGE_NAME_GENERAL_RULE, 'redirect_route' => $redirect, 'state' => $state), array('use_cache' => false));
  1348. }
  1349. function cloud_console_setting() {
  1350. return cloud_api('we7/site/console/setting', array(), array('use_cache' => false));
  1351. }
  1352. function cloud_rgapi_sign() {
  1353. global $_W;
  1354. $cache_key = cache_system_key('cloud_rgapi_sign');
  1355. $cache = cache_load($cache_key);
  1356. if (!empty($cache)) {
  1357. return $cache;
  1358. }
  1359. load()->library('sdk-module');
  1360. try {
  1361. $api = new \W7\Sdk\Module\Api($_W['setting']['site']['key'], $_W['setting']['site']['token'], '', 0, CLOUD_V3API_DOMAIN_PRE);
  1362. $token = $api->login()->toArray();
  1363. if (!empty($token) && is_array($token)) {
  1364. $token = $token['token'];
  1365. } else {
  1366. return error(-1, 'API授权获取站点授权失败,请联系管理员处理!');
  1367. }
  1368. cache_write($cache_key, $token, CACHE_EXPIRE_LONG * 2);
  1369. return urlencode($token);
  1370. } catch (\W7\Sdk\Module\Exceptions\ApiException $e) {
  1371. return error(-1, $e->getResponse()->getBody()->getContents());
  1372. }
  1373. }