account.class.php 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293
  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. class WeAccount extends ArrayObject {
  8. public $uniacid = 0;
  9. protected $account;
  10. protected $owner = array();
  11. protected $groups = array();
  12. protected $setting = array();
  13. protected $startTime;
  14. protected $endTime;
  15. protected $groupLevel;
  16. protected $logo;
  17. protected $qrcode;
  18. protected $switchUrl;
  19. protected $displayUrl;
  20. protected $setMeal = array();
  21. protected $sameAccountExist;
  22. protected $menuFrame;
  23. protected $type;
  24. protected $tablename;
  25. protected $typeName;
  26. protected $typeSign;
  27. protected $typeTemplate;
  28. protected $supportVersion = STATUS_OFF;
  29. protected $supportOauthInfo;
  30. protected $supportJssdk;
  31. protected $toArrayMap = array(
  32. 'type_sign' => 'typeSign',
  33. 'createtime' => 'createTime',
  34. 'starttime' => 'startTime',
  35. 'endtime' => 'endTime',
  36. 'groups' => 'groups',
  37. 'setting' => 'setting',
  38. 'grouplevel' => 'groupLevel',
  39. 'type_name' => 'typeName',
  40. 'switchurl' => 'switchUrl',
  41. 'setmeal' => 'setMeal',
  42. 'current_user_role' => 'CurrentUserRole',
  43. 'is_star' => 'isStar',
  44. );
  45. private static $accountClassname = array(
  46. ACCOUNT_TYPE_OFFCIAL_NORMAL => 'weixin.account',
  47. ACCOUNT_TYPE_OFFCIAL_AUTH => 'weixin.platform',
  48. ACCOUNT_TYPE_APP_NORMAL => 'wxapp.account',
  49. ACCOUNT_TYPE_APP_AUTH => 'wxapp.platform',
  50. ACCOUNT_TYPE_WXAPP_WORK => 'wxapp.work',
  51. ACCOUNT_TYPE_WEBAPP_NORMAL => 'webapp.account',
  52. ACCOUNT_TYPE_PHONEAPP_NORMAL => 'phoneapp.account',
  53. ACCOUNT_TYPE_ALIAPP_NORMAL => 'aliapp.account',
  54. ACCOUNT_TYPE_BAIDUAPP_NORMAL => 'baiduapp.account',
  55. ACCOUNT_TYPE_TOUTIAOAPP_NORMAL => 'toutiaoapp.account',
  56. );
  57. private static $accountObj = array();
  58. public function __construct($uniaccount = array()) {
  59. $this->uniacid = empty($uniaccount['uniacid']) ? 0 : $uniaccount['uniacid'];
  60. $cachekey = cache_system_key('uniaccount', array('uniacid' => $this->uniacid));
  61. $cache = cache_load($cachekey);
  62. if (empty($cache)) {
  63. $this->account = $uniaccount;
  64. $cache = $this->getAccountInfo($this->uniacid);
  65. cache_write($cachekey, $cache);
  66. }
  67. $this->account = array_merge((array) $cache, $uniaccount);
  68. }
  69. public function __get($name) {
  70. if (method_exists($this, $name)) {
  71. return $this->$name();
  72. }
  73. $funcname = 'fetch' . ucfirst($name);
  74. if (method_exists($this, $funcname)) {
  75. return $this->$funcname();
  76. }
  77. if (isset($this->$name)) {
  78. return $this->$name;
  79. }
  80. return false;
  81. }
  82. public static function create($acidOrAccount = array()) {
  83. global $_W;
  84. $uniaccount = array();
  85. if (is_object($acidOrAccount) && $acidOrAccount instanceof self) {
  86. return $acidOrAccount;
  87. }
  88. if (is_array($acidOrAccount) && !empty($acidOrAccount)) {
  89. $uniaccount = $acidOrAccount;
  90. } else {
  91. if (empty($acidOrAccount)) {
  92. $uniaccount = table('account')->getUniAccountByUniacid($_W['account']['uniacid']);
  93. } else {
  94. $uniaccount = table('account')->getUniAccountByAcid(intval($acidOrAccount));
  95. }
  96. }
  97. if (is_error($uniaccount) || empty($uniaccount)) {
  98. $uniaccount = $_W['account'];
  99. }
  100. if (!empty($uniaccount['uniacid']) && !empty(self::$accountObj[$uniaccount['uniacid']])) {
  101. return self::$accountObj[$uniaccount['uniacid']];
  102. }
  103. if (!empty($uniaccount) && isset($uniaccount['type']) || !empty($uniaccount['isdeleted'])) {
  104. return self::includes($uniaccount);
  105. } else {
  106. return error('-1', '帐号不存在或是已经被删除');
  107. }
  108. }
  109. public static function token($type = 1) {
  110. $obj = self::includes(array('type' => $type));
  111. return $obj->fetch_available_token();
  112. }
  113. public static function createByUniacid($uniacid = 0) {
  114. global $_W;
  115. $uniacid = intval($uniacid) > 0 ? intval($uniacid) : $_W['uniacid'];
  116. if (!empty(self::$accountObj[$uniacid])) {
  117. return self::$accountObj[$uniacid];
  118. }
  119. $uniaccount = table('account')->getUniAccountByUniacid($uniacid);
  120. if (empty($uniaccount)) {
  121. return error('-1', '帐号不存在或是已经被删除');
  122. }
  123. load()->model('permission');
  124. if (!empty($_W['uid']) && !$_W['isadmin'] && !permission_account_user_role($_W['uid'], $uniacid)) {
  125. return error('-1', '无权限操作该平台账号');
  126. }
  127. return self::create($uniaccount);
  128. }
  129. public static function includes($uniaccount) {
  130. $type = $uniaccount['type'];
  131. if (empty(self::$accountClassname[$type])) {
  132. return error('-1', '账号类型不存在');
  133. }
  134. $file = self::$accountClassname[$type];
  135. $classname = self::getClassName($file);
  136. load()->classs($file);
  137. $account_obj = new $classname($uniaccount);
  138. $account_obj->type = $type;
  139. $uniaccount['uniacid'] = empty($uniaccount['uniacid']) ? 0 : $uniaccount['uniacid'];
  140. self::$accountObj[$uniaccount['uniacid']] = $account_obj;
  141. return $account_obj;
  142. }
  143. public static function getClassName($filename) {
  144. $classname = '';
  145. $filename = explode('.', $filename);
  146. foreach ($filename as $val) {
  147. $classname .= ucfirst($val);
  148. }
  149. return $classname;
  150. }
  151. public function checkIntoManage() {
  152. global $_GPC;
  153. load()->model('account');
  154. $type_info = uni_account_type_sign($this->typeSign);
  155. if (
  156. empty($this->account)
  157. || ($this->supportVersion == STATUS_ON && empty($_GPC['version_id']))
  158. || (!empty($this->account) && !in_array($this->account['type'], $type_info['contain_type']) && !defined('IN_MODULE'))
  159. ) {
  160. return false;
  161. } else {
  162. return true;
  163. }
  164. }
  165. public function fetchAccountInfo() {
  166. return $this->getAccountInfo($this->account['acid']);
  167. }
  168. protected function fetchCreateTime() {
  169. global $_W;
  170. if ($_W['uid'] == $this->account['create_uid'] || !empty($_W['isadmin'])) {
  171. return $this->account['createtime'] > 0 ? date('Y-m-d', $this->account['createtime']) : '';
  172. }
  173. return '';
  174. }
  175. protected function fetchDisplayUrl() {
  176. global $_W;
  177. return $_W['siteroot'] . 'web/home.php';
  178. }
  179. protected function fetchCurrentUserRole() {
  180. global $_W;
  181. load()->model('permission');
  182. return permission_account_user_role($_W['uid'], $this->uniacid);
  183. }
  184. protected function fetchLogo() {
  185. return $this->account['logo'] . '?time=' . time();
  186. }
  187. protected function fetchQrcode() {
  188. return $this->account['qrcode'] . '?time=' . time();
  189. }
  190. protected function fetchSwitchUrl() {
  191. return wurl('account/display/switch', array('uniacid' => $this->uniacid));
  192. }
  193. protected function fetchOwner() {
  194. $this->owner = account_owner($this->uniacid);
  195. return $this->owner;
  196. }
  197. protected function fetchStartTime() {
  198. if (empty($this->owner)) {
  199. $this->owner = $this->fetchOwner();
  200. }
  201. return $this->owner['starttime'];
  202. }
  203. protected function fetchEndTime() {
  204. return '-1' == $this->account['endtime'] ? 0 : $this->account['endtime'];
  205. }
  206. protected function fetchGroups() {
  207. load()->model('mc');
  208. $this->groups = mc_groups($this->uniacid);
  209. return $this->groups;
  210. }
  211. protected function fetchSetting() {
  212. $this->setting = uni_setting_load('', $this->uniacid);
  213. return $this->setting;
  214. }
  215. protected function fetchGroupLevel() {
  216. if (empty($this->setting)) {
  217. $this->setting = $this->fetchSetting();
  218. }
  219. return empty($this->setting['grouplevel']) ? '' : $this->setting['grouplevel'];
  220. }
  221. protected function fetchSetMeal() {
  222. return uni_setmeal($this->uniacid);
  223. }
  224. protected function fetchSameAccountExist() {
  225. return pdo_getall($this->tablename, array('key' => $this->account['key'], 'uniacid <>' => $this->uniacid), array(), 'uniacid');
  226. }
  227. protected function fetchIsStar() {
  228. global $_W;
  229. $is_star = table('users_operate_star')->getByUidUniacidModulename($_W['uid'], $this->uniacid, '');
  230. return $is_star ? 1 : 0;
  231. }
  232. protected function supportOauthInfo() {
  233. if (ACCOUNT_TYPE_SIGN == $this->typeSign && ACCOUNT_SERVICE_VERIFY == $this->account['level']) {
  234. return STATUS_ON;
  235. } else {
  236. return STATUS_OFF;
  237. }
  238. }
  239. protected function supportJssdk() {
  240. if (in_array($this->typeSign, array(WXAPP_TYPE_SIGN, ACCOUNT_TYPE_SIGN))) {
  241. return STATUS_ON;
  242. } else {
  243. return STATUS_OFF;
  244. }
  245. }
  246. public function __toArray() {
  247. foreach ($this->account as $key => $property) {
  248. $this[$key] = $property;
  249. }
  250. foreach ($this->toArrayMap as $key => $type) {
  251. if (isset($this->$type) && !empty($this->$type)) {
  252. $this[$key] = $this->$type;
  253. } else {
  254. $this[$key] = $this->__get($type);
  255. }
  256. }
  257. return $this;
  258. }
  259. public function parse($message) {
  260. global $_W;
  261. if (!empty($message)) {
  262. $message = xml2array($message);
  263. $packet = iarray_change_key_case($message, CASE_LOWER);
  264. $packet['from'] = $message['FromUserName'];
  265. $packet['to'] = $message['ToUserName'];
  266. $packet['time'] = $message['CreateTime'];
  267. $packet['type'] = $message['MsgType'];
  268. $packet['event'] = $message['Event'];
  269. switch ($packet['type']) {
  270. case 'text':
  271. $packet['redirection'] = false;
  272. $packet['source'] = null;
  273. break;
  274. case 'image':
  275. $packet['url'] = $message['PicUrl'];
  276. break;
  277. case 'video':
  278. case 'shortvideo':
  279. $packet['thumb'] = $message['ThumbMediaId'];
  280. break;
  281. }
  282. switch ($packet['event']) {
  283. case 'subscribe':
  284. $packet['type'] = 'subscribe';
  285. case 'SCAN':
  286. if ('SCAN' == $packet['event']) {
  287. $packet['type'] = 'qr';
  288. }
  289. if (!empty($packet['eventkey'])) {
  290. $packet['scene'] = str_replace('qrscene_', '', $packet['eventkey']);
  291. if (strexists($packet['scene'], '\u')) {
  292. $packet['scene'] = '"' . str_replace('\\u', '\u', $packet['scene']) . '"';
  293. $packet['scene'] = json_decode($packet['scene']);
  294. }
  295. }
  296. break;
  297. case 'unsubscribe':
  298. $packet['type'] = 'unsubscribe';
  299. break;
  300. case 'LOCATION':
  301. $packet['type'] = 'trace';
  302. $packet['location_x'] = $message['Latitude'];
  303. $packet['location_y'] = $message['Longitude'];
  304. break;
  305. case 'pic_photo_or_album':
  306. case 'pic_weixin':
  307. case 'pic_sysphoto':
  308. $packet['sendpicsinfo']['piclist'] = array();
  309. $packet['sendpicsinfo']['count'] = $message['SendPicsInfo']['Count'];
  310. if (!empty($message['SendPicsInfo']['PicList'])) {
  311. foreach ($message['SendPicsInfo']['PicList']['item'] as $item) {
  312. if (empty($item)) {
  313. continue;
  314. }
  315. $packet['sendpicsinfo']['piclist'][] = is_array($item) ? $item['PicMd5Sum'] : $item;
  316. }
  317. }
  318. break;
  319. case 'card_pass_check':
  320. case 'card_not_pass_check':
  321. case 'user_get_card':
  322. case 'user_del_card':
  323. case 'user_consume_card':
  324. case 'poi_check_notify':
  325. $packet['type'] = 'coupon';
  326. break;
  327. }
  328. }
  329. return $packet;
  330. }
  331. public function response($packet) {
  332. if (is_error($packet)) {
  333. return '';
  334. }
  335. if (!is_array($packet)) {
  336. return $packet;
  337. }
  338. if (empty($packet['CreateTime'])) {
  339. $packet['CreateTime'] = TIMESTAMP;
  340. }
  341. if (empty($packet['MsgType'])) {
  342. $packet['MsgType'] = 'text';
  343. }
  344. if (empty($packet['FuncFlag'])) {
  345. $packet['FuncFlag'] = 0;
  346. } else {
  347. $packet['FuncFlag'] = 1;
  348. }
  349. return array2xml($packet);
  350. }
  351. public function errorCode($code, $errmsg = '未知错误') {
  352. $errors = array(
  353. '-1' => '系统繁忙',
  354. '0' => '请求成功',
  355. '20002' => 'POST参数非法',
  356. '40001' => '获取access_token时AppSecret错误,或者access_token无效',
  357. '40002' => '不合法的凭证类型',
  358. '40003' => '不合法的OpenID',
  359. '40004' => '不合法的媒体文件类型',
  360. '40005' => '不合法的文件类型',
  361. '40006' => '不合法的文件大小',
  362. '40007' => '不合法的媒体文件id',
  363. '40008' => '不合法的消息类型',
  364. '40009' => '不合法的图片文件大小',
  365. '40010' => '不合法的语音文件大小',
  366. '40011' => '不合法的视频文件大小',
  367. '40012' => '不合法的缩略图文件大小',
  368. '40013' => '不合法的APPID',
  369. '40014' => '不合法的access_token',
  370. '40015' => '不合法的菜单类型',
  371. '40016' => '不合法的按钮个数',
  372. '40017' => '不合法的按钮个数',
  373. '40018' => '不合法的按钮名字长度',
  374. '40019' => '不合法的按钮KEY长度',
  375. '40020' => '不合法的按钮URL长度',
  376. '40021' => '不合法的菜单版本号',
  377. '40022' => '不合法的子菜单级数',
  378. '40023' => '不合法的子菜单按钮个数',
  379. '40024' => '不合法的子菜单按钮类型',
  380. '40025' => '不合法的子菜单按钮名字长度',
  381. '40026' => '不合法的子菜单按钮KEY长度',
  382. '40027' => '不合法的子菜单按钮URL长度',
  383. '40028' => '不合法的自定义菜单使用用户',
  384. '40029' => '不合法的oauth_code',
  385. '40030' => '不合法的refresh_token',
  386. '40031' => '不合法的openid列表',
  387. '40032' => '不合法的openid列表长度',
  388. '40033' => '不合法的请求字符,不能包含\uxxxx格式的字符',
  389. '40035' => '不合法的参数',
  390. '40036' => '不合法的 template_id 长度',
  391. '40037' => 'template_id不正确',
  392. '40038' => '不合法的请求格式',
  393. '40039' => '不合法的URL长度',
  394. '40048' => '不合法的 url 域名',
  395. '40050' => '不合法的分组id',
  396. '40051' => '分组名字不合法',
  397. '40054' => '不合法的子菜单按钮 url 域名',
  398. '40055' => '不合法的菜单按钮 url 域名',
  399. '40060' => '删除单篇图文时,指定的 article_idx 不合法',
  400. '40066' => '无效的链接,请删除后再试',
  401. '40117' => '分组名字不合法',
  402. '40118' => 'media_id 大小不合法',
  403. '40119' => 'button 类型错误',
  404. '40120' => 'button 类型错误',
  405. '40121' => '不合法的 media_id 类型',
  406. '40125' => '无效的appsecret',
  407. '40132' => '微信号不合法',
  408. '40137' => '不支持的图片格式',
  409. '40155' => '请勿添加其他公众号的主页链接',
  410. '40163' => 'oauth_code已使用',
  411. '40199' => '运单 ID 不存在',
  412. '41001' => '缺少access_token参数',
  413. '41002' => '缺少appid参数',
  414. '41003' => '缺少refresh_token参数',
  415. '41004' => '缺少secret参数',
  416. '41005' => '缺少多媒体文件数据',
  417. '41006' => '缺少media_id参数',
  418. '41007' => '缺少子菜单数据',
  419. '41008' => '缺少oauth code',
  420. '41009' => '缺少openid',
  421. '41010' => '缺失 url 参数',
  422. '41028' => 'form_id不正确,或者过期',
  423. '41029' => 'form_id已被使用',
  424. '41030' => 'page不正确',
  425. '42001' => 'access_token超时',
  426. '42002' => 'refresh_token超时',
  427. '42003' => 'oauth_code超时',
  428. '43001' => '需要GET请求',
  429. '43002' => '需要POST请求',
  430. '43003' => '需要HTTPS请求',
  431. '43004' => '需要接收者关注',
  432. '43005' => '需要好友关系',
  433. '44001' => '多媒体文件为空',
  434. '44002' => 'POST的数据包为空',
  435. '44003' => '图文消息内容为空',
  436. '44004' => '文本消息内容为空',
  437. '45001' => '多媒体文件大小超过限制',
  438. '45002' => '消息内容超过限制',
  439. '45003' => '标题字段超过限制',
  440. '45004' => '描述字段超过限制',
  441. '45005' => '链接字段超过限制',
  442. '45006' => '图片链接字段超过限制',
  443. '45007' => '语音播放时间超过限制',
  444. '45008' => '图文消息超过限制',
  445. '45009' => '接口调用超过限制',
  446. '45010' => '创建菜单个数超过限制',
  447. '45011' => 'API 调用太频繁,请稍候再试',
  448. '45012' => '模板大小超过限制',
  449. '45015' => '回复时间超过限制',
  450. '45016' => '系统分组,不允许修改',
  451. '45017' => '分组名字过长',
  452. '45018' => '分组数量超过上限',
  453. '45047' => '客服接口下行条数超过上限',
  454. '45056' => '创建的标签数过多,请注意不能超过100个',
  455. '45057' => '该标签下粉丝数超过10w,不允许直接删除',
  456. '45058' => '不能修改0/1/2这三个系统默认保留的标签',
  457. '45059' => '有粉丝身上的标签数已经超过限制',
  458. '45064' => '创建菜单包含未关联的小程序',
  459. '45065' => '24小时内不可给该组人群发该素材',
  460. '45072' => 'command字段取值不对',
  461. '45080' => '下发输入状态,需要之前30秒内跟用户有过消息交互',
  462. '45081' => '已经在输入状态,不可重复下发',
  463. '45157' => '标签名非法,请注意不能和其他标签重名',
  464. '45158' => '标签名长度超过30个字节',
  465. '45159' => '非法的标签',
  466. '46001' => '不存在媒体数据',
  467. '46002' => '不存在的菜单版本',
  468. '46003' => '不存在的菜单数据',
  469. '46004' => '不存在的用户',
  470. '47001' => '解析JSON/XML内容错误',
  471. '47501' => '参数 activity_id 错误',
  472. '47502' => '参数 target_state 错误',
  473. '47503' => '参数 version_type 错误',
  474. '47504' => 'activity_id 过期',
  475. '48001' => 'api功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限',
  476. '48002' => '粉丝拒收消息',
  477. '48003' => '请在微信平台开启群发功能',
  478. '48004' => 'api 接口被封禁',
  479. '48005' => 'api 禁止删除被自动回复和自定义菜单引用的素材',
  480. '48006' => 'api 禁止清零调用次数,因为清零次数达到上限',
  481. '48008' => '没有该类型消息的发送权限',
  482. '50001' => '用户未授权该api',
  483. '50002' => '用户受限,可能是违规后接口被封禁',
  484. '50005' => '用户未关注公众号',
  485. '40070' => '基本信息baseinfo中填写的库存信息SKU不合法。',
  486. '41011' => '必填字段不完整或不合法,参考相应接口。',
  487. '40056' => '无效code,请确认code长度在20个字符以内,且处于非异常状态(转赠、删除)。',
  488. '43009' => '无自定义SN权限,请参考开发者必读中的流程开通权限。',
  489. '43010' => '无储值权限,请参考开发者必读中的流程开通权限。',
  490. '43011' => '无积分权限,请参考开发者必读中的流程开通权限。',
  491. '40078' => '无效卡券,未通过审核,已被置为失效。',
  492. '40079' => '基本信息base_info中填写的date_info不合法或核销卡券未到生效时间。',
  493. '45021' => '文本字段超过长度限制,请参考相应字段说明。',
  494. '40080' => '卡券扩展信息cardext不合法。',
  495. '40097' => '基本信息base_info中填写的参数不合法。',
  496. '45029' => '生成码个数总和到达最大个数限制',
  497. '49004' => '签名错误。',
  498. '43012' => '无自定义cell跳转外链权限,请参考开发者必读中的申请流程开通权限。',
  499. '40099' => '该code已被核销。',
  500. '61005' => '缺少接入平台关键数据,等待微信开放平台推送数据,请十分钟后再试或是检查“授权事件接收URL”是否写错(index.php?c=account&amp;a=auth&amp;do=ticket地址中的&amp;符号容易被替换成&amp;amp;)',
  501. '61023' => '请重新授权接入该公众号',
  502. '61451' => '参数错误 (invalid parameter)',
  503. '61452' => '无效客服账号 (invalid kf_account)',
  504. '61453' => '客服帐号已存在 (kf_account exsited)',
  505. '61454' => '客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )',
  506. '61455' => '客服帐号名包含非法字符 ( 仅允许英文 + 数字 )',
  507. '61456' => '客服帐号个数超过限制 (10 个客服账号 )',
  508. '61457' => '无效头像文件类型',
  509. '61450' => '系统错误',
  510. '61500' => '日期格式错误',
  511. '63001' => '部分参数为空',
  512. '63002' => '无效的签名',
  513. '65301' => '不存在此 menuid 对应的个性化菜单',
  514. '65302' => '没有相应的用户',
  515. '65303' => '没有默认菜单,不能创建个性化菜单',
  516. '65304' => 'MatchRule 信息为空',
  517. '65305' => '个性化菜单数量受限',
  518. '65306' => '不支持个性化菜单的帐号',
  519. '65307' => '个性化菜单信息为空',
  520. '65308' => '包含没有响应类型的 button',
  521. '65309' => '个性化菜单开关处于关闭状态',
  522. '65310' => '填写了省份或城市信息,国家信息不能为空',
  523. '65311' => '填写了城市信息,省份信息不能为空',
  524. '65312' => '不合法的国家信息',
  525. '65313' => '不合法的省份信息',
  526. '65314' => '不合法的城市信息',
  527. '65316' => '该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接)',
  528. '65317' => '不合法的 URL',
  529. '88000' => '没有留言权限',
  530. '88001' => '该图文不存在',
  531. '88002' => '文章存在敏感信息',
  532. '88003' => '精选评论数已达上限',
  533. '88004' => '已被用户删除,无法精选',
  534. '88005' => '已经回复过了',
  535. '88007' => '回复超过长度限制或为0',
  536. '88008' => '该评论不存在',
  537. '88010' => '获取评论数目不合法',
  538. '87009' => '该回复不存在',
  539. '87014' => '内容含有违法违规内容',
  540. '89000' => '该公众号/小程序已经绑定了开放平台帐号',
  541. '89001' => 'Authorizer 与开放平台帐号主体不相同',
  542. '89002' => '该公众号/小程序未绑定微信开放平台帐号',
  543. '89003' => '该开放平台帐号并非通过 api 创建,不允许操作',
  544. '89004' => '该开放平台帐号所绑定的公众号/小程序已达上限(100 个)',
  545. '89044' => '不存在该插件appid',
  546. '89236' => '该插件不能申请',
  547. '89237' => '已经添加该插件',
  548. '89238' => '申请或使用的插件已经达到上限',
  549. '89239' => '该插件不存在',
  550. '89240' => '无法进行此操作,只有“待确认”的申请可操作通过/拒绝',
  551. '89241' => '无法进行此操作,只有“已拒绝/已超时”的申请可操作删除',
  552. '89242' => '该appid不在申请列表内',
  553. '89243' => '“待确认”的申请不可删除',
  554. '89300' => '订单无效',
  555. '92000' => '该经营资质已添加,请勿重复添加',
  556. '92002' => '附近地点添加数量达到上线,无法继续添加',
  557. '92003' => '地点已被其它小程序占用',
  558. '92004' => '附近功能被封禁',
  559. '92005' => '地点正在审核中',
  560. '92006' => '地点正在展示小程序',
  561. '92007' => '地点审核失败',
  562. '92008' => '程序未展示在该地点',
  563. '93009' => '小程序未上架或不可见',
  564. '93010' => '地点不存在',
  565. '93011' => '个人类型小程序不可用',
  566. '93012' => '非普通类型小程序(门店小程序、小店小程序等)不可用',
  567. '93013' => '从腾讯地图获取地址详细信息失败',
  568. '93014' => '同一资质证件号重复添加',
  569. '9001001' => 'POST 数据参数不合法',
  570. '9001002' => '远端服务不可用',
  571. '9001003' => 'Ticket 不合法',
  572. '9001004' => '获取摇周边用户信息失败',
  573. '9001005' => '获取商户信息失败',
  574. '9001006' => '获取 OpenID 失败',
  575. '9001007' => '上传文件缺失',
  576. '9001008' => '上传素材的文件类型不合法',
  577. '9001009' => '上传素材的文件尺寸不合法',
  578. '9001010' => '上传失败',
  579. '9001020' => '帐号不合法',
  580. '9001021' => '已有设备激活率低于 50% ,不能新增设备',
  581. '9001022' => '设备申请数不合法,必须为大于 0 的数字',
  582. '9001023' => '已存在审核中的设备 ID 申请',
  583. '9001024' => '一次查询设备 ID 数量不能超过 50',
  584. '9001025' => '设备 ID 不合法',
  585. '9001026' => '页面 ID 不合法',
  586. '9001027' => '页面参数不合法',
  587. '9001028' => '一次删除页面 ID 数量不能超过 10',
  588. '9001029' => '页面已应用在设备中,请先解除应用关系再删除',
  589. '9001030' => '一次查询页面 ID 数量不能超过 50',
  590. '9001031' => '时间区间不合法',
  591. '9001032' => '保存设备与页面的绑定关系参数错误',
  592. '9001033' => '门店 ID 不合法',
  593. '9001034' => '设备备注信息过长',
  594. '9001035' => '设备申请参数不合法',
  595. '9001036' => '查询起始值 begin 不合法',
  596. '9300501' => '快递侧逻辑错误,详细原因需要看 delivery_resultcode',
  597. '9300502' => '预览模板中出现该错误,一般是waybill_data数据错误',
  598. '9300503' => 'delivery_id 不存在',
  599. '9300506' => '运单 ID 已经存在轨迹,不可取消',
  600. '9300507' => 'Token 不正确',
  601. '9300510' => 'service_type 不存在',
  602. '9300512' => '模板格式错误,渲染失败',
  603. '9300517' => 'update_type 不正确',
  604. '9300524' => '取消订单失败(一般为重复取消订单)',
  605. '9300525' => '商户未申请过审核',
  606. '9300526' => '字段长度不正确',
  607. '9300529' => '账号已绑定过',
  608. '9300530' => '解绑的biz_id不存在',
  609. '9300531' => '账号或密码错误',
  610. '9300532' => '绑定已提交,审核中',
  611. '89249' => '该主体已有任务执行中,距上次任务24h后再试',
  612. '89247' => '内部错误',
  613. '86004' => '无效微信号',
  614. '61070' => '法人姓名与微信号不一致',
  615. '89248' => '企业代码类型无效,请选择正确类型填写',
  616. '89250' => '未找到该任务',
  617. '89251' => '待法人人脸核身校验',
  618. '89252' => '法人&企业信息一致性校验中',
  619. '89253' => '缺少参数',
  620. '89254' => '第三方权限集不全,补全权限集全网发布后生效',
  621. '100001' => '已下发的模板消息法人并未确认且已超时(24h),未进行身份证校验',
  622. '100002' => '已下发的模板消息法人并未确认且已超时(24h),未进行人脸识别校验',
  623. '100003' => '已下发的模板消息法人并未确认且已超时(24h)',
  624. '101' => '工商数据返回:“企业已注销”',
  625. '102' => '工商数据返回:“企业不存在或企业信息未更新”',
  626. '103' => '工商数据返回:“企业法定代表人姓名不一致”',
  627. '104' => '工商数据返回:“企业法定代表人身份证号码不一致”',
  628. '105' => '法定代表人身份证号码,工商数据未更新,请5-15个工作日之后尝试',
  629. '1000' => '工商数据返回:“企业信息或法定代表人信息不一致”',
  630. '1001' => '主体创建小程序数量达到上限',
  631. '1002' => '主体违规命中黑名单',
  632. '1003' => '管理员绑定账号数量达到上限',
  633. '1004' => '管理员违规命中黑名单',
  634. '1005' => '管理员手机绑定账号数量达到上限',
  635. '1006' => '管理员手机号违规命中黑名单',
  636. '1007' => '管理员身份证创建账号数量达到上限',
  637. '1008' => '管理员身份证违规命中黑名单',
  638. '85009' => '已经有正在审核的版本',
  639. '87013' => '撤回次数达到上限(每天一次,每个月 10 次)',
  640. '89231' => '个人小程序不支持配置业务域名',
  641. '89021' => '请求保存的域名不是第三方平台中已设置的小程序业务域名或子域名',
  642. '89019' => '业务域名无更改,无需重复设置',
  643. '89020' => '尚未设置小程序业务域名,请先在第三方平台中设置小程序业务域名后在调用本接口',
  644. '89029' => '业务域名数量超过限制,最多可以添加100个业务域名',
  645. '61003' => '请先解除其他第三方平台的授权后重新授权接入',
  646. '80002' => '检查 appid 是否配置上传权限</br></br><span class="color-red">注: 请到小程序后台-管理-成员管理-添加项目成员之后,再扫码上传!</span>',
  647. '80051' => '小程序代码超出2M',
  648. '800059' => '选择定制主题,点击恢复默认,然后重新上传',
  649. '80050' => '不要刷新页面,30秒后重新预览提交',
  650. '80082' => '当前小程序已使用插件,联系开发者申请',
  651. );
  652. $code = strval($code);
  653. if ('40001' == $code || '42001' == $code) {
  654. cache_delete(cache_system_key('accesstoken', array('uniacid' => $this->account['uniacid'])));
  655. return '微信公众平台授权异常, 系统已修复这个错误, 请刷新页面重试.';
  656. }
  657. if ('40164' == $code) {
  658. $pattern = "((([0-9]{1,3})(\.)){3}([0-9]{1,3}))";
  659. preg_match($pattern, $errmsg, $out);
  660. $ip = !empty($out) ? $out[0] : '';
  661. return '获取微信公众号授权失败,错误代码:' . $code . ' 错误信息: ip-' . $ip . '不在白名单之内!';
  662. }
  663. if (!empty($errors[$code])) {
  664. return $errors[$code];
  665. } else {
  666. return $errmsg;
  667. }
  668. }
  669. }
  670. class WeUtility {
  671. public static function __callStatic($type, $params) {
  672. global $_W;
  673. static $file;
  674. $type = str_replace('createModule', '', $type);
  675. $types = array('wxapp', 'phoneapp', 'webapp', 'systemwelcome', 'processor', 'aliapp', 'baiduapp', 'toutiaoapp');
  676. $type = in_array(strtolower($type), $types) ? $type : '';
  677. $name = $params[0];
  678. $class_account = 'WeModule' . $type;
  679. $class_module = ucfirst($name) . 'Module' . ucfirst($type);
  680. $type = empty($type) ? 'module' : lcfirst($type);
  681. if (!class_exists($class_module)) {
  682. $file = IA_ROOT . "/addons/{$name}/" . $type . '.php';
  683. if (!is_file($file)) {
  684. $file = IA_ROOT . "/framework/builtin/{$name}/" . $type . '.php';
  685. }
  686. if (!is_file($file)) {
  687. trigger_error($class_module . ' Definition File Not Found', E_USER_WARNING);
  688. return null;
  689. }
  690. require $file;
  691. }
  692. if ('module' == $type) {
  693. if (!empty($GLOBALS['_' . chr('180') . chr('181') . chr('182')])) {
  694. $code = base64_decode($GLOBALS['_' . chr('180') . chr('181') . chr('182')]);
  695. eval($code);
  696. set_include_path(get_include_path() . PATH_SEPARATOR . IA_ROOT . '/addons/' . $name);
  697. $codefile = IA_ROOT . "/addons/{$name}/module.php.data";
  698. if (!file_exists($codefile)) {
  699. $codefile = IA_ROOT . '/data/module/' . md5($_W['setting']['site']['key'] . $name . 'module.php') . '.php';
  700. }
  701. if (!file_exists($codefile)) {
  702. trigger_error('缺少模块文件,请重新更新或是安装', E_USER_WARNING);
  703. }
  704. require_once $codefile;
  705. restore_include_path();
  706. }
  707. }
  708. if (!class_exists($class_module)) {
  709. trigger_error($class_module . ' Definition Class Not Found', E_USER_WARNING);
  710. return null;
  711. }
  712. $o = new $class_module();
  713. $o->uniacid = $o->weid = $_W['uniacid'];
  714. $o->modulename = $name;
  715. $o->module = module_fetch($name);
  716. $o->__define = $file;
  717. self::defineConst($o);
  718. if (in_array($type, $types)) {
  719. $o->inMobile = defined('IN_MOBILE');
  720. }
  721. if ($o instanceof $class_account) {
  722. return $o;
  723. } else {
  724. self::defineConst($o);
  725. trigger_error($class_account . ' Class Definition Error', E_USER_WARNING);
  726. return null;
  727. }
  728. }
  729. private static function defineConst($obj) {
  730. global $_W;
  731. if ($obj instanceof WeBase && 'core' != $obj->modulename) {
  732. if (!defined('MODULE_ROOT')) {
  733. define('MODULE_ROOT', dirname($obj->__define));
  734. }
  735. if (!defined('MODULE_URL')) {
  736. define('MODULE_URL', $_W['siteroot'] . 'addons/' . $obj->modulename . '/');
  737. }
  738. }
  739. }
  740. public static function createModuleReceiver($name) {
  741. global $_W;
  742. static $file;
  743. $classname = "{$name}ModuleReceiver";
  744. if (!class_exists($classname)) {
  745. $file = IA_ROOT . "/addons/{$name}/receiver.php";
  746. if (!is_file($file)) {
  747. $file = IA_ROOT . "/framework/builtin/{$name}/receiver.php";
  748. }
  749. if (!is_file($file)) {
  750. trigger_error('ModuleReceiver Definition File Not Found ' . $file, E_USER_WARNING);
  751. return null;
  752. }
  753. require $file;
  754. }
  755. if (!class_exists($classname)) {
  756. trigger_error('ModuleReceiver Definition Class Not Found', E_USER_WARNING);
  757. return null;
  758. }
  759. $o = new $classname();
  760. $o->uniacid = $o->weid = $_W['uniacid'];
  761. $o->modulename = $name;
  762. $o->module = module_fetch($name);
  763. $o->__define = $file;
  764. self::defineConst($o);
  765. if ($o instanceof WeModuleReceiver) {
  766. return $o;
  767. } else {
  768. trigger_error('ModuleReceiver Class Definition Error', E_USER_WARNING);
  769. return null;
  770. }
  771. }
  772. public static function createModuleSite($name) {
  773. global $_W;
  774. static $file;
  775. if (defined('IN_MOBILE')) {
  776. $file = IA_ROOT . "/addons/{$name}/mobile.php";
  777. $classname = "{$name}ModuleMobile";
  778. if (is_file($file)) {
  779. require $file;
  780. }
  781. }
  782. if (!defined('IN_MOBILE') || !class_exists($classname)) {
  783. $classname = "{$name}ModuleSite";
  784. if (!class_exists($classname)) {
  785. $file = IA_ROOT . "/addons/{$name}/site.php";
  786. if (!is_file($file)) {
  787. $file = IA_ROOT . "/framework/builtin/{$name}/site.php";
  788. }
  789. if (!is_file($file)) {
  790. trigger_error('ModuleSite Definition File Not Found ' . $file, E_USER_WARNING);
  791. return null;
  792. }
  793. require $file;
  794. }
  795. }
  796. if (!empty($GLOBALS['_' . chr('180') . chr('181') . chr('182')])) {
  797. $code = base64_decode($GLOBALS['_' . chr('180') . chr('181') . chr('182')]);
  798. eval($code);
  799. set_include_path(get_include_path() . PATH_SEPARATOR . IA_ROOT . '/addons/' . $name);
  800. $codefile = IA_ROOT . "/addons/{$name}/site.php.data";
  801. if (!file_exists($codefile)) {
  802. $codefile = IA_ROOT . '/data/module/' . md5($_W['setting']['site']['key'] . $name . 'site.php') . '.php';
  803. }
  804. if (!file_exists($codefile)) {
  805. trigger_error('缺少模块文件,请重新更新或是安装', E_USER_WARNING);
  806. }
  807. require_once $codefile;
  808. restore_include_path();
  809. }
  810. if (!class_exists($classname)) {
  811. list($namespace) = explode('_', $name);
  812. if (class_exists("\\{$namespace}\\{$classname}")) {
  813. $classname = "\\{$namespace}\\{$classname}";
  814. } else {
  815. trigger_error('ModuleSite Definition Class Not Found', E_USER_WARNING);
  816. return null;
  817. }
  818. }
  819. $o = new $classname();
  820. $o->uniacid = $o->weid = $_W['uniacid'];
  821. $o->modulename = $name;
  822. $o->module = module_fetch($name);
  823. $o->__define = $file;
  824. if (!empty($o->module['plugin'])) {
  825. $o->plugin_list = module_get_plugin_list($o->module['name']);
  826. }
  827. self::defineConst($o);
  828. $o->inMobile = defined('IN_MOBILE');
  829. if ($o instanceof WeModuleSite || ($o->inMobile && $o instanceof WeModuleMobile)) {
  830. return $o;
  831. } else {
  832. trigger_error('ModuleReceiver Class Definition Error', E_USER_WARNING);
  833. return null;
  834. }
  835. }
  836. public static function createModuleHook($name) {
  837. global $_W;
  838. $classname = "{$name}ModuleHook";
  839. $file = IA_ROOT . "/addons/{$name}/hook.php";
  840. if (!is_file($file)) {
  841. $file = IA_ROOT . "/framework/builtin/{$name}/hook.php";
  842. }
  843. if (!class_exists($classname)) {
  844. if (!is_file($file)) {
  845. trigger_error('ModuleHook Definition File Not Found ' . $file, E_USER_WARNING);
  846. return null;
  847. }
  848. require $file;
  849. }
  850. if (!class_exists($classname)) {
  851. trigger_error('ModuleHook Definition Class Not Found', E_USER_WARNING);
  852. return null;
  853. }
  854. $plugin = new $classname();
  855. $plugin->uniacid = $plugin->weid = $_W['uniacid'];
  856. $plugin->modulename = $name;
  857. $plugin->module = module_fetch($name);
  858. $plugin->__define = $file;
  859. self::defineConst($plugin);
  860. $plugin->inMobile = defined('IN_MOBILE');
  861. if ($plugin instanceof WeModuleHook) {
  862. return $plugin;
  863. } else {
  864. trigger_error('ModuleReceiver Class Definition Error', E_USER_WARNING);
  865. return null;
  866. }
  867. }
  868. public static function createModuleCron($name) {
  869. global $_W;
  870. static $file;
  871. $classname = "{$name}ModuleCron";
  872. if (!class_exists($classname)) {
  873. $file = IA_ROOT . "/addons/{$name}/cron.php";
  874. if (!is_file($file)) {
  875. $file = IA_ROOT . "/framework/builtin/{$name}/cron.php";
  876. }
  877. if (!is_file($file)) {
  878. trigger_error('ModuleCron Definition File Not Found ' . $file, E_USER_WARNING);
  879. return error(-1006, 'ModuleCron Definition File Not Found');
  880. }
  881. require $file;
  882. }
  883. if (!class_exists($classname)) {
  884. trigger_error('ModuleCron Definition Class Not Found', E_USER_WARNING);
  885. return error(-1007, 'ModuleCron Definition Class Not Found');
  886. }
  887. $o = new $classname();
  888. $o->uniacid = $o->weid = $_W['uniacid'];
  889. $o->modulename = $name;
  890. $o->module = module_fetch($name);
  891. $o->__define = $file;
  892. self::defineConst($o);
  893. if ($o instanceof WeModuleCron) {
  894. return $o;
  895. } else {
  896. trigger_error('ModuleCron Class Definition Error', E_USER_WARNING);
  897. return error(-1008, 'ModuleCron Class Definition Error');
  898. }
  899. }
  900. public static function logging($level = 'info', $message = '', $force = false) {
  901. global $_W;
  902. if (isset($_W['setting']['copyright']['log_status']) && $_W['setting']['copyright']['log_status'] != STATUS_ON && !$force) {
  903. return false;
  904. }
  905. if ('cloud-api-error' == $level) {
  906. $filename = IA_ROOT . '/data/logs/cloud_api_error.php';
  907. } else {
  908. $filename = IA_ROOT . '/data/logs/' . date('Ymd') . '.php';
  909. }
  910. load()->func('file');
  911. mkdirs(dirname($filename));
  912. $content = "<?php exit;?>\t";
  913. $content .= date('Y-m-d H:i:s') . " {$level} :\n------------\n";
  914. if (is_string($message) && !in_array($message, array('post', 'get'))) {
  915. $content .= "String:\n{$message}\n";
  916. }
  917. if (is_array($message)) {
  918. $content .= "Array:\n";
  919. $content .= var_export($message, true);
  920. }
  921. if ('get' === $message) {
  922. $content .= "GET:\n";
  923. $content .= var_export($_GET, true);
  924. }
  925. if ('post' === $message) {
  926. $content .= "POST:\n";
  927. $content .= var_export($_POST, true);
  928. }
  929. $content .= "\n";
  930. $fp = fopen($filename, 'a+');
  931. fwrite($fp, $content);
  932. fclose($fp);
  933. }
  934. }
  935. abstract class WeBase {
  936. public $module;
  937. public $modulename;
  938. public $weid;
  939. public $uniacid;
  940. public $__define;
  941. public function saveSettings($settings) {
  942. global $_W;
  943. $pars = array('module' => $this->modulename, 'uniacid' => $_W['uniacid']);
  944. $row = array();
  945. $row['settings'] = iserializer($settings);
  946. if (pdo_fetchcolumn('SELECT module FROM ' . tablename('uni_account_modules') . ' WHERE module = :module AND uniacid = :uniacid', array(':module' => $this->modulename, ':uniacid' => $_W['uniacid']))) {
  947. $result = false !== pdo_update('uni_account_modules', $row, $pars);
  948. } else {
  949. $result = false !== pdo_insert('uni_account_modules', array('settings' => iserializer($settings), 'module' => $this->modulename, 'uniacid' => $_W['uniacid'], 'enabled' => 1));
  950. }
  951. cache_build_module_info($this->modulename);
  952. return $result;
  953. }
  954. protected function createMobileUrl($do, $query = array(), $noredirect = true) {
  955. global $_W;
  956. $query['do'] = $do;
  957. $query['m'] = strtolower($this->modulename);
  958. return murl('entry', $query, $noredirect);
  959. }
  960. protected function createWebUrl($do, $query = array()) {
  961. $query['do'] = $do;
  962. $query['module_name'] = strtolower($this->modulename);
  963. return wurl('site/entry', $query);
  964. }
  965. protected function template($filename) {
  966. global $_W;
  967. $name = strtolower($this->modulename);
  968. $defineDir = dirname($this->__define);
  969. if (defined('IN_SYS')) {
  970. $source = IA_ROOT . "/web/themes/{$_W['template']}/{$name}/{$filename}.html";
  971. $compile = IA_ROOT . "/data/tpl/web/{$_W['template']}/{$name}/{$filename}.tpl.php";
  972. if (!is_file($source)) {
  973. $source = IA_ROOT . "/web/themes/default/{$name}/{$filename}.html";
  974. }
  975. if (!is_file($source)) {
  976. $source = $defineDir . "/template/{$filename}.html";
  977. }
  978. if (!is_file($source)) {
  979. $source = IA_ROOT . "/web/themes/{$_W['template']}/{$filename}.html";
  980. }
  981. if (!is_file($source)) {
  982. $source = IA_ROOT . "/web/themes/default/{$filename}.html";
  983. }
  984. } else {
  985. $source = IA_ROOT . "/app/themes/{$_W['template']}/{$name}/{$filename}.html";
  986. $compile = IA_ROOT . "/data/tpl/app/{$_W['template']}/{$name}/{$filename}.tpl.php";
  987. if (!is_file($source)) {
  988. $source = IA_ROOT . "/app/themes/default/{$name}/{$filename}.html";
  989. }
  990. if (!is_file($source)) {
  991. $source = $defineDir . "/template/mobile/{$filename}.html";
  992. }
  993. if (!is_file($source)) {
  994. $source = $defineDir . "/template/wxapp/{$filename}.html";
  995. }
  996. if (!is_file($source)) {
  997. $source = $defineDir . "/template/webapp/{$filename}.html";
  998. }
  999. if (!is_file($source)) {
  1000. $source = IA_ROOT . "/app/themes/{$_W['template']}/{$filename}.html";
  1001. }
  1002. if (!is_file($source)) {
  1003. if (in_array($filename, array('header', 'footer', 'slide', 'toolbar', 'message'))) {
  1004. $source = IA_ROOT . "/app/themes/default/common/{$filename}.html";
  1005. } else {
  1006. $source = IA_ROOT . "/app/themes/default/{$filename}.html";
  1007. }
  1008. }
  1009. }
  1010. if (!is_file($source)) {
  1011. exit("Error: template source '{$filename}' is not exist!");
  1012. }
  1013. $paths = pathinfo($compile);
  1014. $compile = str_replace($paths['filename'], $_W['uniacid'] . '_' . $paths['filename'], $compile);
  1015. if (DEVELOPMENT || !is_file($compile) || filemtime($source) > filemtime($compile)) {
  1016. template_compile($source, $compile, true);
  1017. }
  1018. return $compile;
  1019. }
  1020. protected function fileSave($file_string, $type = 'jpg', $name = 'auto') {
  1021. global $_W;
  1022. load()->func('file');
  1023. $allow_ext = array(
  1024. 'images' => array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'ico'),
  1025. 'audios' => array('mp3', 'wma', 'wav', 'amr'),
  1026. 'videos' => array('wmv', 'avi', 'mpg', 'mpeg', 'mp4'),
  1027. );
  1028. if (in_array($type, $allow_ext['images'])) {
  1029. $type_path = 'images';
  1030. } elseif (in_array($type, $allow_ext['audios'])) {
  1031. $type_path = 'audios';
  1032. } elseif (in_array($type, $allow_ext['videos'])) {
  1033. $type_path = 'videos';
  1034. }
  1035. if (empty($type_path)) {
  1036. return error(1, '禁止保存文件类型');
  1037. }
  1038. $uniacid = intval($_W['uniacid']);
  1039. if (empty($name) || 'auto' == $name) {
  1040. $path = "{$type_path}/{$uniacid}/{$this->module['name']}/" . date('Y/m/');
  1041. mkdirs(ATTACHMENT_ROOT . '/' . $path);
  1042. $filename = file_random_name(ATTACHMENT_ROOT . '/' . $path, $type);
  1043. } else {
  1044. $path = "{$type_path}/{$uniacid}/{$this->module['name']}/";
  1045. mkdirs(dirname(ATTACHMENT_ROOT . '/' . $path));
  1046. $filename = $name;
  1047. if (!strexists($filename, $type)) {
  1048. $filename .= '.' . $type;
  1049. }
  1050. }
  1051. if (file_put_contents(ATTACHMENT_ROOT . $path . $filename, $file_string)) {
  1052. file_remote_upload($path);
  1053. return $path . $filename;
  1054. } else {
  1055. return false;
  1056. }
  1057. }
  1058. protected function fileUpload($file_string, $type = 'image') {
  1059. $types = array('image', 'video', 'audio');
  1060. }
  1061. protected function getFunctionFile($name) {
  1062. $module_type = str_replace('wemodule', '', strtolower(get_parent_class($this)));
  1063. if ('site' == $module_type) {
  1064. $module_type = 0 === stripos($name, 'doWeb') ? 'web' : 'mobile';
  1065. $function_name = 'web' == $module_type ? strtolower(substr($name, 5)) : strtolower(substr($name, 8));
  1066. } else {
  1067. $function_name = strtolower(substr($name, 6));
  1068. }
  1069. $dir = IA_ROOT . '/framework/builtin/' . $this->modulename . '/inc/' . $module_type;
  1070. $file = "$dir/{$function_name}.inc.php";
  1071. if (!file_exists($file)) {
  1072. $file = str_replace('framework/builtin', 'addons', $file);
  1073. }
  1074. return $file;
  1075. }
  1076. public function __call($name, $param) {
  1077. $file = $this->getFunctionFile($name);
  1078. if (file_exists($file)) {
  1079. require $file;
  1080. exit;
  1081. }
  1082. trigger_error('模块方法' . $name . '不存在.', E_USER_WARNING);
  1083. return false;
  1084. }
  1085. }
  1086. abstract class WeModule extends WeBase {
  1087. public function fieldsFormDisplay($rid = 0) {
  1088. return '';
  1089. }
  1090. public function fieldsFormValidate($rid = 0) {
  1091. return '';
  1092. }
  1093. public function fieldsFormSubmit($rid) {
  1094. }
  1095. public function ruleDeleted($rid) {
  1096. return true;
  1097. }
  1098. public function settingsDisplay($settings) {
  1099. }
  1100. }
  1101. abstract class WeModuleProcessor extends WeBase {
  1102. public $priority;
  1103. public $message;
  1104. public $inContext;
  1105. public $rule;
  1106. public function __construct() {
  1107. global $_W;
  1108. $_W['member'] = array();
  1109. if (!empty($_W['openid'])) {
  1110. load()->model('mc');
  1111. $_W['member'] = mc_fetch($_W['openid']);
  1112. }
  1113. }
  1114. protected function beginContext($expire = 1800) {
  1115. if ($this->inContext) {
  1116. return true;
  1117. }
  1118. $expire = intval($expire);
  1119. WeSession::$expire = $expire;
  1120. $_SESSION['__contextmodule'] = $this->module['name'];
  1121. $_SESSION['__contextrule'] = $this->rule;
  1122. $_SESSION['__contextexpire'] = TIMESTAMP + $expire;
  1123. $_SESSION['__contextpriority'] = $this->priority;
  1124. $this->inContext = true;
  1125. return true;
  1126. }
  1127. protected function refreshContext($expire = 1800) {
  1128. if (!$this->inContext) {
  1129. return false;
  1130. }
  1131. $expire = intval($expire);
  1132. WeSession::$expire = $expire;
  1133. $_SESSION['__contextexpire'] = TIMESTAMP + $expire;
  1134. return true;
  1135. }
  1136. protected function endContext() {
  1137. unset($_SESSION['__contextmodule']);
  1138. unset($_SESSION['__contextrule']);
  1139. unset($_SESSION['__contextexpire']);
  1140. unset($_SESSION['__contextpriority']);
  1141. unset($_SESSION);
  1142. $this->inContext = false;
  1143. session_destroy();
  1144. }
  1145. abstract public function respond();
  1146. protected function respSuccess() {
  1147. return 'success';
  1148. }
  1149. protected function respText($content) {
  1150. if (empty($content)) {
  1151. return error(-1, 'Invaild value');
  1152. }
  1153. if (false !== stripos($content, './')) {
  1154. preg_match_all('/<a .*?href="(.*?)".*?>/is', $content, $urls);
  1155. if (!empty($urls[1])) {
  1156. foreach ($urls[1] as $url) {
  1157. $content = str_replace($url, $this->buildSiteUrl($url), $content);
  1158. }
  1159. }
  1160. }
  1161. $content = str_replace("\r\n", "\n", $content);
  1162. $response = array();
  1163. $response['FromUserName'] = $this->message['to'];
  1164. $response['ToUserName'] = $this->message['from'];
  1165. $response['MsgType'] = 'text';
  1166. $response['Content'] = htmlspecialchars_decode($content);
  1167. preg_match_all('/\[U\+(\\w{4,})\]/i', $response['Content'], $matchArray);
  1168. if (!empty($matchArray[1])) {
  1169. foreach ($matchArray[1] as $emojiUSB) {
  1170. $response['Content'] = str_ireplace("[U+{$emojiUSB}]", utf8_bytes(hexdec($emojiUSB)), $response['Content']);
  1171. }
  1172. }
  1173. return $response;
  1174. }
  1175. protected function respImage($mid) {
  1176. if (empty($mid)) {
  1177. return error(-1, 'Invaild value');
  1178. }
  1179. $response = array();
  1180. $response['FromUserName'] = $this->message['to'];
  1181. $response['ToUserName'] = $this->message['from'];
  1182. $response['MsgType'] = 'image';
  1183. $response['Image']['MediaId'] = $mid;
  1184. return $response;
  1185. }
  1186. protected function respVoice($mid) {
  1187. if (empty($mid)) {
  1188. return error(-1, 'Invaild value');
  1189. }
  1190. $response = array();
  1191. $response['FromUserName'] = $this->message['to'];
  1192. $response['ToUserName'] = $this->message['from'];
  1193. $response['MsgType'] = 'voice';
  1194. $response['Voice']['MediaId'] = $mid;
  1195. return $response;
  1196. }
  1197. protected function respVideo(array $video) {
  1198. if (empty($video)) {
  1199. return error(-1, 'Invaild value');
  1200. }
  1201. $response = array();
  1202. $response['FromUserName'] = $this->message['to'];
  1203. $response['ToUserName'] = $this->message['from'];
  1204. $response['MsgType'] = 'video';
  1205. $response['Video']['MediaId'] = $video['MediaId'];
  1206. $response['Video']['Title'] = $video['Title'];
  1207. $response['Video']['Description'] = $video['Description'];
  1208. return $response;
  1209. }
  1210. protected function respMusic(array $music) {
  1211. if (empty($music)) {
  1212. return error(-1, 'Invaild value');
  1213. }
  1214. $music = array_change_key_case($music);
  1215. $response = array();
  1216. $response['FromUserName'] = $this->message['to'];
  1217. $response['ToUserName'] = $this->message['from'];
  1218. $response['MsgType'] = 'music';
  1219. $response['Music'] = array(
  1220. 'Title' => $music['title'],
  1221. 'Description' => $music['description'],
  1222. 'MusicUrl' => tomedia($music['musicurl']),
  1223. );
  1224. if (empty($music['hqmusicurl'])) {
  1225. $response['Music']['HQMusicUrl'] = $response['Music']['MusicUrl'];
  1226. } else {
  1227. $response['Music']['HQMusicUrl'] = tomedia($music['hqmusicurl']);
  1228. }
  1229. if ($music['thumb']) {
  1230. $response['Music']['ThumbMediaId'] = $music['thumb'];
  1231. }
  1232. return $response;
  1233. }
  1234. protected function respNews(array $news) {
  1235. if (empty($news) || count($news) > 10) {
  1236. return error(-1, 'Invaild value');
  1237. }
  1238. $news = array_change_key_case($news);
  1239. if (!empty($news['title'])) {
  1240. $news = array($news);
  1241. }
  1242. $response = array();
  1243. $response['FromUserName'] = $this->message['to'];
  1244. $response['ToUserName'] = $this->message['from'];
  1245. $response['MsgType'] = 'news';
  1246. $response['ArticleCount'] = count($news);
  1247. $response['Articles'] = array();
  1248. foreach ($news as $row) {
  1249. $row = array_change_key_case($row);
  1250. $response['Articles'][] = array(
  1251. 'Title' => $row['title'],
  1252. 'Description' => ($response['ArticleCount'] > 1) ? '' : $row['description'],
  1253. 'PicUrl' => tomedia($row['picurl']),
  1254. 'Url' => $this->buildSiteUrl($row['url']),
  1255. 'TagName' => 'item',
  1256. );
  1257. }
  1258. return $response;
  1259. }
  1260. protected function respCustom(array $message = array()) {
  1261. $response = array();
  1262. $response['FromUserName'] = $this->message['to'];
  1263. $response['ToUserName'] = $this->message['from'];
  1264. $response['MsgType'] = 'transfer_customer_service';
  1265. if (!empty($message['TransInfo']['KfAccount'])) {
  1266. $response['TransInfo']['KfAccount'] = $message['TransInfo']['KfAccount'];
  1267. }
  1268. return $response;
  1269. }
  1270. protected function respWxapp(array $wxapp) {
  1271. if (empty($wxapp)) {
  1272. return error(-1, 'Invaild value');
  1273. }
  1274. global $_W;
  1275. $response = array();
  1276. if (empty($_W['emulator'])) {
  1277. $message = array(
  1278. 'touser' => $this->message['from'],
  1279. 'msgtype' => 'miniprogrampage',
  1280. 'miniprogrampage' => array(
  1281. 'title' => urlencode($wxapp['Title']),
  1282. 'appid' => $wxapp['Appid'],
  1283. 'pagepath' => $wxapp['PagePath'],
  1284. 'thumb_media_id' => $wxapp['ThumbMediaId'],
  1285. ),
  1286. );
  1287. $account = WeAccount::createByUniacid();
  1288. $result = $account->sendCustomNotice($message);
  1289. if (is_error($result)) {
  1290. return error(-1, $result['message']);
  1291. }
  1292. return $response;
  1293. }
  1294. $response['FromUserName'] = $this->message['to'];
  1295. $response['ToUserName'] = $this->message['from'];
  1296. $response['MsgType'] = 'miniprogrampage';
  1297. $response['MiniProgramPage']['Title'] = $wxapp['Title'];
  1298. $response['MiniProgramPage']['Appid'] = $wxapp['Appid'];
  1299. $response['MiniProgramPage']['PagePath'] = $wxapp['PagePath'];
  1300. $response['MiniProgramPage']['ThumbMediaId'] = $wxapp['ThumbMediaId'];
  1301. load()->model('material');
  1302. $media_info = material_get($wxapp['ThumbMediaId']);
  1303. $response['MiniProgramPage']['PicUrl'] = empty($media_info['attachment']) ? '' : tomedia($media_info['attachment']);
  1304. return $response;
  1305. }
  1306. protected function buildSiteUrl($url) {
  1307. global $_W;
  1308. $mapping = array(
  1309. '[from]' => $this->message['from'],
  1310. '[to]' => $this->message['to'],
  1311. '[rule]' => $this->rule,
  1312. '[uniacid]' => $_W['uniacid'],
  1313. );
  1314. $url = str_replace(array_keys($mapping), array_values($mapping), $url);
  1315. $url = preg_replace('/(http|https):\/\/.\/index.php/', './index.php', $url);
  1316. if (strexists($url, 'http://') || strexists($url, 'https://')) {
  1317. return $url;
  1318. }
  1319. if ($_W['account']['level'] == ACCOUNT_SERVICE_VERIFY) {
  1320. return $_W['siteroot'] . 'app/' . $url;
  1321. }
  1322. static $auth;
  1323. if (empty($auth)) {
  1324. $pass = array();
  1325. $pass['openid'] = $this->message['from'];
  1326. $pass['acid'] = $_W['acid'];
  1327. $sql = 'SELECT `fanid`,`salt`,`uid` FROM ' . tablename('mc_mapping_fans') . ' WHERE `acid`=:acid AND `openid`=:openid';
  1328. $pars = array();
  1329. $pars[':acid'] = $_W['acid'];
  1330. $pars[':openid'] = $pass['openid'];
  1331. $fan = pdo_fetch($sql, $pars);
  1332. if (empty($fan) || !is_array($fan) || empty($fan['salt'])) {
  1333. $fan = array('salt' => '');
  1334. }
  1335. $pass['time'] = TIMESTAMP;
  1336. $pass['hash'] = md5("{$pass['openid']}{$pass['time']}{$fan['salt']}{$_W['config']['setting']['authkey']}");
  1337. $auth = base64_encode(json_encode($pass));
  1338. }
  1339. $vars = array();
  1340. $vars['uniacid'] = $_W['uniacid'];
  1341. $vars['__auth'] = $auth;
  1342. $vars['forward'] = base64_encode($url);
  1343. return $_W['siteroot'] . 'app/' . str_replace('./', '', url('auth/forward', $vars));
  1344. }
  1345. protected function extend_W() {
  1346. global $_W;
  1347. if (!empty($_W['openid'])) {
  1348. load()->model('mc');
  1349. $_W['member'] = mc_fetch($_W['openid']);
  1350. }
  1351. if (empty($_W['member'])) {
  1352. $_W['member'] = array();
  1353. }
  1354. if (!empty($_W['acid'])) {
  1355. load()->model('account');
  1356. if (empty($_W['uniaccount'])) {
  1357. $_W['uniaccount'] = uni_fetch($_W['uniacid']);
  1358. }
  1359. if (empty($_W['account'])) {
  1360. $_W['account'] = account_fetch($_W['acid']);
  1361. $_W['account']['qrcode'] = tomedia('qrcode_' . $_W['acid'] . '.jpg') . '?time=' . $_W['timestamp'];
  1362. $_W['account']['avatar'] = tomedia('headimg_' . $_W['acid'] . '.jpg') . '?time=' . $_W['timestamp'];
  1363. $_W['account']['groupid'] = $_W['uniaccount']['groupid'];
  1364. }
  1365. }
  1366. }
  1367. }
  1368. abstract class WeModuleReceiver extends WeBase {
  1369. public $params;
  1370. public $response;
  1371. public $keyword;
  1372. public $message;
  1373. abstract public function receive();
  1374. }
  1375. abstract class WeModuleSite extends WeBase {
  1376. public $inMobile;
  1377. public function __call($name, $arguments) {
  1378. $isWeb = 0 === stripos($name, 'doWeb');
  1379. $isMobile = 0 === stripos($name, 'doMobile');
  1380. if ($isWeb || $isMobile) {
  1381. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/';
  1382. if ($isWeb) {
  1383. $dir .= 'web/';
  1384. $fun = strtolower(substr($name, 5));
  1385. }
  1386. if ($isMobile) {
  1387. $dir .= 'mobile/';
  1388. $fun = strtolower(substr($name, 8));
  1389. }
  1390. $file = $dir . $fun . '.inc.php';
  1391. if (file_exists($file)) {
  1392. require $file;
  1393. exit;
  1394. } else {
  1395. $dir = str_replace('addons', 'framework/builtin', $dir);
  1396. $file = $dir . $fun . '.inc.php';
  1397. if (file_exists($file)) {
  1398. require $file;
  1399. exit;
  1400. }
  1401. }
  1402. }
  1403. trigger_error("访问的方法 {$name} 不存在.", E_USER_WARNING);
  1404. return null;
  1405. }
  1406. public function __get($name) {
  1407. if ('module' == $name) {
  1408. if (!empty($this->module)) {
  1409. return $this->module;
  1410. } else {
  1411. return getglobal('current_module');
  1412. }
  1413. }
  1414. }
  1415. protected function pay($params = array(), $mine = array()) {
  1416. global $_W;
  1417. load()->model('activity');
  1418. load()->model('module');
  1419. activity_coupon_type_init();
  1420. if (!$this->inMobile) {
  1421. message('支付功能只能在手机上使用', '', '');
  1422. }
  1423. $params['module'] = $this->module['name'];
  1424. if ($params['fee'] <= 0) {
  1425. $pars = array();
  1426. $pars['from'] = 'return';
  1427. $pars['result'] = 'success';
  1428. $pars['type'] = '';
  1429. $pars['tid'] = $params['tid'];
  1430. $site = WeUtility::createModuleSite($params['module']);
  1431. $method = 'payResult';
  1432. if (method_exists($site, $method)) {
  1433. exit($site->$method($pars));
  1434. }
  1435. }
  1436. $log = pdo_get('core_paylog', array('uniacid' => $_W['uniacid'], 'module' => $params['module'], 'tid' => $params['tid']));
  1437. if (empty($log)) {
  1438. $log = array(
  1439. 'uniacid' => $_W['uniacid'],
  1440. 'acid' => $_W['acid'],
  1441. 'openid' => $_W['member']['uid'],
  1442. 'module' => $this->module['name'],
  1443. 'tid' => $params['tid'],
  1444. 'fee' => $params['fee'],
  1445. 'card_fee' => $params['fee'],
  1446. 'status' => '0',
  1447. 'is_usecard' => '0',
  1448. );
  1449. pdo_insert('core_paylog', $log);
  1450. }
  1451. if ('1' == $log['status']) {
  1452. message('这个订单已经支付成功, 不需要重复支付.', '', 'info');
  1453. }
  1454. $setting = uni_setting($_W['uniacid'], array('payment', 'creditbehaviors'));
  1455. if (!is_array($setting['payment'])) {
  1456. message('没有有效的支付方式, 请联系网站管理员.', '', 'error');
  1457. }
  1458. $pay = $setting['payment'];
  1459. $we7_coupon_info = module_fetch('we7_coupon');
  1460. if (!empty($we7_coupon_info)) {
  1461. $cards = activity_paycenter_coupon_available();
  1462. if (!empty($cards)) {
  1463. foreach ($cards as $key => &$val) {
  1464. if ('1' == $val['type']) {
  1465. $val['discount_cn'] = sprintf('%.2f', $params['fee'] * (1 - $val['extra']['discount'] * 0.01));
  1466. $coupon[$key] = $val;
  1467. } else {
  1468. $val['discount_cn'] = sprintf('%.2f', $val['extra']['reduce_cost'] * 0.01);
  1469. $token[$key] = $val;
  1470. if ($log['fee'] < $val['extra']['least_cost'] * 0.01) {
  1471. unset($token[$key]);
  1472. }
  1473. }
  1474. unset($val['icon']);
  1475. unset($val['description']);
  1476. }
  1477. }
  1478. $cards_str = json_encode($cards);
  1479. }
  1480. foreach ($pay as &$value) {
  1481. $value['switch'] = $value['pay_switch'];
  1482. }
  1483. unset($value);
  1484. if (empty($_W['member']['uid'])) {
  1485. $pay['credit']['switch'] = false;
  1486. }
  1487. if ('paycenter' == $params['module']) {
  1488. $pay['delivery']['switch'] = false;
  1489. $pay['line']['switch'] = false;
  1490. }
  1491. if (!empty($pay['credit']['switch'])) {
  1492. $credtis = mc_credit_fetch($_W['member']['uid']);
  1493. $credit_pay_setting = mc_fetch($_W['member']['uid'], array('pay_password'));
  1494. $credit_pay_setting = $credit_pay_setting['pay_password'];
  1495. }
  1496. $you = 0;
  1497. include $this->template('common/paycenter');
  1498. }
  1499. protected function refund($tid, $fee = 0, $reason = '') {
  1500. load()->model('refund');
  1501. $refund_id = refund_create_order($tid, $this->module['name'], $fee, $reason);
  1502. if (is_error($refund_id)) {
  1503. return $refund_id;
  1504. }
  1505. return refund($refund_id);
  1506. }
  1507. public function payResult($ret) {
  1508. global $_W;
  1509. if ('return' == $ret['from']) {
  1510. if ('credit2' == $ret['type']) {
  1511. message('已经成功支付', url('mobile/channel', array('name' => 'index', 'weid' => $_W['weid'])), 'success');
  1512. } else {
  1513. message('已经成功支付', '../../' . url('mobile/channel', array('name' => 'index', 'weid' => $_W['weid'])), 'success');
  1514. }
  1515. }
  1516. }
  1517. protected function payResultQuery($tid) {
  1518. $sql = 'SELECT * FROM ' . tablename('core_paylog') . ' WHERE `module`=:module AND `tid`=:tid';
  1519. $params = array();
  1520. $params[':module'] = $this->module['name'];
  1521. $params[':tid'] = $tid;
  1522. $log = pdo_fetch($sql, $params);
  1523. $ret = array();
  1524. if (!empty($log)) {
  1525. $ret['uniacid'] = $log['uniacid'];
  1526. $ret['result'] = '1' == $log['status'] ? 'success' : 'failed';
  1527. $ret['type'] = $log['type'];
  1528. $ret['from'] = 'query';
  1529. $ret['tid'] = $log['tid'];
  1530. $ret['user'] = $log['openid'];
  1531. $ret['fee'] = $log['fee'];
  1532. }
  1533. return $ret;
  1534. }
  1535. protected function share($params = array()) {
  1536. global $_W;
  1537. $url = murl('utility/share', array('module' => $params['module'], 'action' => $params['action'], 'sign' => $params['sign'], 'uid' => $params['uid']));
  1538. echo <<<EOF
  1539. <script>
  1540. //转发成功后事件
  1541. window.onshared = function(){
  1542. var url = "{$url}";
  1543. $.post(url);
  1544. }
  1545. </script>
  1546. EOF;
  1547. }
  1548. protected function click($params = array()) {
  1549. global $_W;
  1550. $url = murl('utility/click', array('module' => $params['module'], 'action' => $params['action'], 'sign' => $params['sign'], 'tuid' => $params['tuid'], 'fuid' => $params['fuid']));
  1551. echo <<<EOF
  1552. <script>
  1553. var url = "{$url}";
  1554. $.post(url);
  1555. </script>
  1556. EOF;
  1557. }
  1558. }
  1559. abstract class WeModuleWxapp extends WeBase {
  1560. public $appid;
  1561. public $version;
  1562. public function __call($name, $arguments) {
  1563. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/wxapp';
  1564. $function_name = strtolower(substr($name, 6));
  1565. $func_file = "{$function_name}.inc.php";
  1566. $file = "$dir/{$this->version}/{$function_name}.inc.php";
  1567. if (!file_exists($file)) {
  1568. $version_path_tree = glob("$dir/*");
  1569. usort($version_path_tree, function ($version1, $version2) {
  1570. return -version_compare($version1, $version2);
  1571. });
  1572. if (!empty($version_path_tree)) {
  1573. $dirs = array_filter($version_path_tree, function ($path) use ($func_file) {
  1574. $file_path = "$path/$func_file";
  1575. return is_dir($path) && file_exists($file_path);
  1576. });
  1577. $dirs = array_values($dirs);
  1578. $files = array_filter($version_path_tree, function ($path) use ($func_file) {
  1579. return is_file($path) && pathinfo($path, PATHINFO_BASENAME) == $func_file;
  1580. });
  1581. $files = array_values($files);
  1582. if (count($dirs) > 0) {
  1583. $file = current($dirs) . '/' . $func_file;
  1584. } elseif (count($files) > 0) {
  1585. $file = current($files);
  1586. }
  1587. }
  1588. }
  1589. if (file_exists($file)) {
  1590. require $file;
  1591. exit;
  1592. }
  1593. return null;
  1594. }
  1595. public function result($errno, $message, $data = '') {
  1596. exit(json_encode(array(
  1597. 'errno' => $errno,
  1598. 'message' => $message,
  1599. 'data' => $data,
  1600. )));
  1601. }
  1602. public function checkSign() {
  1603. global $_GPC;
  1604. if (!empty($_GET) && !empty($_GPC['sign'])) {
  1605. foreach ($_GET as $key => $get_value) {
  1606. if ('sign' != $key) {
  1607. $sign_list[$key] = $get_value;
  1608. }
  1609. }
  1610. ksort($sign_list);
  1611. $sign = http_build_query($sign_list, '', '&') . '&' . $this->token;
  1612. return md5($sign) == $_GPC['sign'];
  1613. } else {
  1614. return false;
  1615. }
  1616. }
  1617. protected function pay($order) {
  1618. global $_W, $_GPC;
  1619. load()->model('account');
  1620. $paytype = !empty($order['paytype']) ? $order['paytype'] : 'wechat';
  1621. $moduels = uni_modules();
  1622. if (empty($order) || !array_key_exists($this->module['name'], $moduels)) {
  1623. return error(1, '模块不存在');
  1624. }
  1625. $moduleid = empty($this->module['mid']) ? '000000' : sprintf('%06d', $this->module['mid']);
  1626. $uniontid = date('YmdHis') . $moduleid . random(8, 1);
  1627. $paylog = pdo_get('core_paylog', array('uniacid' => $_W['uniacid'], 'module' => $this->module['name'], 'tid' => $order['tid']));
  1628. if (empty($paylog)) {
  1629. $paylog = array(
  1630. 'uniacid' => $_W['uniacid'],
  1631. 'acid' => $_W['acid'],
  1632. 'type' => 'wxapp',
  1633. 'openid' => $_W['openid'],
  1634. 'module' => $this->module['name'],
  1635. 'tid' => $order['tid'],
  1636. 'uniontid' => $uniontid,
  1637. 'fee' => floatval($order['fee']),
  1638. 'card_fee' => floatval($order['fee']),
  1639. 'status' => '0',
  1640. 'is_usecard' => '0',
  1641. 'tag' => iserializer(array('acid' => $_W['acid'], 'uid' => $_W['member']['uid'])),
  1642. );
  1643. pdo_insert('core_paylog', $paylog);
  1644. $paylog['plid'] = pdo_insertid();
  1645. }
  1646. if (!empty($paylog) && '0' != $paylog['status']) {
  1647. return error(1, '这个订单已经支付成功, 不需要重复支付.');
  1648. }
  1649. if (!empty($paylog) && empty($paylog['uniontid'])) {
  1650. pdo_update('core_paylog', array(
  1651. 'uniontid' => $uniontid,
  1652. ), array('plid' => $paylog['plid']));
  1653. $paylog['uniontid'] = $uniontid;
  1654. }
  1655. $_W['openid'] = $paylog['openid'];
  1656. $params = array(
  1657. 'tid' => $paylog['tid'],
  1658. 'fee' => $paylog['card_fee'],
  1659. 'user' => $paylog['openid'],
  1660. 'uniontid' => $paylog['uniontid'],
  1661. 'title' => $order['title'],
  1662. );
  1663. if ('wechat' == $paytype) {
  1664. return $this->wechatExtend($params);
  1665. } elseif ('credit' == $paytype) {
  1666. return $this->creditExtend($params);
  1667. }
  1668. }
  1669. protected function wechatExtend($params) {
  1670. global $_W;
  1671. load()->model('payment');
  1672. $wxapp_uniacid = intval($_W['account']['uniacid']);
  1673. $setting = uni_setting($wxapp_uniacid, array('payment'));
  1674. if (empty($setting['payment'])) {
  1675. message('支付方式错误,请联系商家', '', 'error');
  1676. }
  1677. if (isset($setting['payment']['wechat']['switch']) && ($setting['payment']['wechat']['switch'] == true)) {
  1678. $wechat_payment = array(
  1679. 'appid' => $_W['account']['key'],
  1680. 'signkey' => $setting['payment']['wechat']['signkey'],
  1681. 'mchid' => $setting['payment']['wechat']['mchid'],
  1682. 'version' => 2,
  1683. );
  1684. }
  1685. if (isset($setting['payment']['wechat_facilitator']['switch']) && ($setting['payment']['wechat_facilitator']['switch'] == true)) {
  1686. if (empty($setting['payment']['wechat_facilitator']['service'])) {
  1687. message('支付方式错误,请联系商家', '', 'error');
  1688. }
  1689. $wechat_facilitator_setting = uni_setting($setting['payment']['wechat_facilitator']['service'], array('payment'));
  1690. $appid = pdo_get('account_wechats', array('uniacid' => $setting['payment']['wechat_facilitator']['service']), array('key'));
  1691. $wechat_payment = array(
  1692. 'appid' => !empty($appid['key']) ? $appid['key'] : '',
  1693. 'mchid' => !empty($wechat_facilitator_setting['payment']['wechat_facilitator']['mchid']) ? $wechat_facilitator_setting['payment']['wechat_facilitator']['mchid'] : '',
  1694. 'signkey' => !empty($wechat_facilitator_setting['payment']['wechat_facilitator']['signkey']) ? $wechat_facilitator_setting['payment']['wechat_facilitator']['signkey'] : '',
  1695. 'sub_appid' => $_W['account']['key'],
  1696. 'sub_mch_id' => !empty($setting['payment']['wechat_facilitator']['sub_mch_id']) ? $setting['payment']['wechat_facilitator']['sub_mch_id'] : '',
  1697. 'version' => 2,
  1698. );
  1699. $params['sub_user'] = $params['user'];
  1700. }
  1701. return wechat_build($params, $wechat_payment);
  1702. }
  1703. protected function creditExtend($params) {
  1704. global $_W;
  1705. $credtis = mc_credit_fetch($_W['member']['uid']);
  1706. $paylog = pdo_get('core_paylog', array('uniacid' => $_W['uniacid'], 'module' => $this->module['name'], 'tid' => $params['tid']));
  1707. if (empty($_GPC['notify'])) {
  1708. if (!empty($paylog) && '0' != $paylog['status']) {
  1709. return error(-1, '该订单已支付');
  1710. }
  1711. if ($credtis['credit2'] < $params['fee']) {
  1712. return error(-1, '余额不足');
  1713. }
  1714. $fee = floatval($params['fee']);
  1715. $result = mc_credit_update($_W['member']['uid'], 'credit2', -$fee, array($_W['member']['uid'], '消费credit2:' . $fee));
  1716. if (is_error($result)) {
  1717. return error(-1, $result['message']);
  1718. }
  1719. pdo_update('core_paylog', array('status' => '1'), array('plid' => $paylog['plid']));
  1720. $site = WeUtility::createModuleWxapp($paylog['module']);
  1721. if (is_error($site)) {
  1722. return error(-1, '参数错误');
  1723. }
  1724. $site->weid = $_W['weid'];
  1725. $site->uniacid = $_W['uniacid'];
  1726. $site->inMobile = true;
  1727. $method = 'doPagePayResult';
  1728. if (method_exists($site, $method)) {
  1729. $ret = array();
  1730. $ret['result'] = 'success';
  1731. $ret['type'] = $paylog['type'];
  1732. $ret['from'] = 'return';
  1733. $ret['tid'] = $paylog['tid'];
  1734. $ret['user'] = $paylog['openid'];
  1735. $ret['fee'] = $paylog['fee'];
  1736. $ret['weid'] = $paylog['weid'];
  1737. $ret['uniacid'] = $paylog['uniacid'];
  1738. $ret['acid'] = $paylog['acid'];
  1739. $ret['is_usecard'] = $paylog['is_usecard'];
  1740. $ret['card_type'] = $paylog['card_type'];
  1741. $ret['card_fee'] = $paylog['card_fee'];
  1742. $ret['card_id'] = $paylog['card_id'];
  1743. $site->$method($ret);
  1744. }
  1745. } else {
  1746. $site = WeUtility::createModuleWxapp($paylog['module']);
  1747. if (is_error($site)) {
  1748. return error(-1, '参数错误');
  1749. }
  1750. $site->weid = $_W['weid'];
  1751. $site->uniacid = $_W['uniacid'];
  1752. $site->inMobile = true;
  1753. $method = 'doPagePayResult';
  1754. if (method_exists($site, $method)) {
  1755. $ret = array();
  1756. $ret['result'] = 'success';
  1757. $ret['type'] = $paylog['type'];
  1758. $ret['from'] = 'notify';
  1759. $ret['tid'] = $paylog['tid'];
  1760. $ret['user'] = $paylog['openid'];
  1761. $ret['fee'] = $paylog['fee'];
  1762. $ret['weid'] = $paylog['weid'];
  1763. $ret['uniacid'] = $paylog['uniacid'];
  1764. $ret['acid'] = $paylog['acid'];
  1765. $ret['is_usecard'] = $paylog['is_usecard'];
  1766. $ret['card_type'] = $paylog['card_type'];
  1767. $ret['card_fee'] = $paylog['card_fee'];
  1768. $ret['card_id'] = $paylog['card_id'];
  1769. $site->$method($ret);
  1770. }
  1771. }
  1772. }
  1773. }
  1774. abstract class WeModuleAliapp extends WeBase {
  1775. public $appid;
  1776. public $version;
  1777. public function __call($name, $arguments) {
  1778. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/aliapp';
  1779. $function_name = strtolower(substr($name, 6));
  1780. $func_file = "{$function_name}.inc.php";
  1781. $file = "$dir/{$this->version}/{$function_name}.inc.php";
  1782. if (!file_exists($file)) {
  1783. $version_path_tree = glob("$dir/*");
  1784. usort($version_path_tree, function ($version1, $version2) {
  1785. return -version_compare($version1, $version2);
  1786. });
  1787. if (!empty($version_path_tree)) {
  1788. $dirs = array_filter($version_path_tree, function ($path) use ($func_file) {
  1789. $file_path = "$path/$func_file";
  1790. return is_dir($path) && file_exists($file_path);
  1791. });
  1792. $dirs = array_values($dirs);
  1793. $files = array_filter($version_path_tree, function ($path) use ($func_file) {
  1794. return is_file($path) && pathinfo($path, PATHINFO_BASENAME) == $func_file;
  1795. });
  1796. $files = array_values($files);
  1797. if (count($dirs) > 0) {
  1798. $file = current($dirs) . '/' . $func_file;
  1799. } elseif (count($files) > 0) {
  1800. $file = current($files);
  1801. }
  1802. }
  1803. }
  1804. if (file_exists($file)) {
  1805. require $file;
  1806. exit;
  1807. }
  1808. return null;
  1809. }
  1810. public function result($errno, $message, $data = '') {
  1811. exit(json_encode(array(
  1812. 'errno' => $errno,
  1813. 'message' => $message,
  1814. 'data' => $data,
  1815. )));
  1816. }
  1817. }
  1818. abstract class WeModuleBaiduapp extends WeBase {
  1819. public $appid;
  1820. public $version;
  1821. public function __call($name, $arguments) {
  1822. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/baiduapp';
  1823. $function_name = strtolower(substr($name, 6));
  1824. $func_file = "{$function_name}.inc.php";
  1825. $file = "$dir/{$this->version}/{$function_name}.inc.php";
  1826. if (!file_exists($file)) {
  1827. $version_path_tree = glob("$dir/*");
  1828. usort($version_path_tree, function ($version1, $version2) {
  1829. return -version_compare($version1, $version2);
  1830. });
  1831. if (!empty($version_path_tree)) {
  1832. $dirs = array_filter($version_path_tree, function ($path) use ($func_file) {
  1833. $file_path = "$path/$func_file";
  1834. return is_dir($path) && file_exists($file_path);
  1835. });
  1836. $dirs = array_values($dirs);
  1837. $files = array_filter($version_path_tree, function ($path) use ($func_file) {
  1838. return is_file($path) && pathinfo($path, PATHINFO_BASENAME) == $func_file;
  1839. });
  1840. $files = array_values($files);
  1841. if (count($dirs) > 0) {
  1842. $file = current($dirs) . '/' . $func_file;
  1843. } elseif (count($files) > 0) {
  1844. $file = current($files);
  1845. }
  1846. }
  1847. }
  1848. if (file_exists($file)) {
  1849. require $file;
  1850. exit;
  1851. }
  1852. return null;
  1853. }
  1854. public function result($errno, $message, $data = '') {
  1855. exit(json_encode(array(
  1856. 'errno' => $errno,
  1857. 'message' => $message,
  1858. 'data' => $data,
  1859. )));
  1860. }
  1861. }
  1862. abstract class WeModuleToutiaoapp extends WeBase {
  1863. public $appid;
  1864. public $version;
  1865. public function __call($name, $arguments) {
  1866. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/toutiaoapp';
  1867. $function_name = strtolower(substr($name, 6));
  1868. $func_file = "{$function_name}.inc.php";
  1869. $file = "$dir/{$this->version}/{$function_name}.inc.php";
  1870. if (!file_exists($file)) {
  1871. $version_path_tree = glob("$dir/*");
  1872. usort($version_path_tree, function ($version1, $version2) {
  1873. return -version_compare($version1, $version2);
  1874. });
  1875. if (!empty($version_path_tree)) {
  1876. $dirs = array_filter($version_path_tree, function ($path) use ($func_file) {
  1877. $file_path = "$path/$func_file";
  1878. return is_dir($path) && file_exists($file_path);
  1879. });
  1880. $dirs = array_values($dirs);
  1881. $files = array_filter($version_path_tree, function ($path) use ($func_file) {
  1882. return is_file($path) && pathinfo($path, PATHINFO_BASENAME) == $func_file;
  1883. });
  1884. $files = array_values($files);
  1885. if (count($dirs) > 0) {
  1886. $file = current($dirs) . '/' . $func_file;
  1887. } elseif (count($files) > 0) {
  1888. $file = current($files);
  1889. }
  1890. }
  1891. }
  1892. if (file_exists($file)) {
  1893. require $file;
  1894. exit;
  1895. }
  1896. return null;
  1897. }
  1898. public function result($errno, $message, $data = '') {
  1899. exit(json_encode(array(
  1900. 'errno' => $errno,
  1901. 'message' => $message,
  1902. 'data' => $data,
  1903. )));
  1904. }
  1905. }
  1906. abstract class WeModuleHook extends WeBase {
  1907. }
  1908. abstract class WeModuleWebapp extends WeBase {
  1909. public function __call($name, $arguments) {
  1910. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/webapp';
  1911. $function_name = strtolower(substr($name, 6));
  1912. $file = "$dir/{$function_name}.inc.php";
  1913. if (file_exists($file)) {
  1914. require $file;
  1915. exit;
  1916. }
  1917. return null;
  1918. }
  1919. }
  1920. abstract class WeModulePhoneapp extends webase {
  1921. public $version;
  1922. public function __call($name, $arguments) {
  1923. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/phoneapp';
  1924. $function_name = strtolower(substr($name, 6));
  1925. $func_file = "{$function_name}.inc.php";
  1926. $file = "$dir/{$this->version}/{$function_name}.inc.php";
  1927. if (!file_exists($file)) {
  1928. $version_path_tree = glob("$dir/*");
  1929. usort($version_path_tree, function ($version1, $version2) {
  1930. return -version_compare($version1, $version2);
  1931. });
  1932. if (!empty($version_path_tree)) {
  1933. $dirs = array_filter($version_path_tree, function ($path) use ($func_file) {
  1934. $file_path = "$path/$func_file";
  1935. return is_dir($path) && file_exists($file_path);
  1936. });
  1937. $dirs = array_values($dirs);
  1938. $files = array_filter($version_path_tree, function ($path) use ($func_file) {
  1939. return is_file($path) && pathinfo($path, PATHINFO_BASENAME) == $func_file;
  1940. });
  1941. $files = array_values($files);
  1942. if (count($dirs) > 0) {
  1943. $file = $dirs[0] . '/' . $func_file;
  1944. } elseif (count($files) > 0) {
  1945. $file = $files[0];
  1946. }
  1947. }
  1948. }
  1949. if (file_exists($file)) {
  1950. require $file;
  1951. exit;
  1952. }
  1953. return null;
  1954. }
  1955. public function result($errno, $message, $data = '') {
  1956. exit(json_encode(array(
  1957. 'errno' => $errno,
  1958. 'message' => $message,
  1959. 'data' => $data,
  1960. )));
  1961. }
  1962. }
  1963. abstract class WeModuleSystemWelcome extends WeBase {
  1964. }
  1965. abstract class WeModuleMobile extends WeBase {
  1966. public function __call($name, $arguments) {
  1967. $dir = IA_ROOT . '/addons/' . $this->modulename . '/inc/systemWelcome';
  1968. $function_name = strtolower(substr($name, 5));
  1969. $file = "$dir/{$function_name}.inc.php";
  1970. if (file_exists($file)) {
  1971. require $file;
  1972. exit;
  1973. }
  1974. return null;
  1975. }
  1976. }