wxapp.account.class.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. load()->func('communication');
  8. class WxappAccount extends WeAccount {
  9. protected $tablename = 'account_wxapp';
  10. protected $menuFrame = 'wxapp';
  11. protected $type = ACCOUNT_TYPE_APP_NORMAL;
  12. protected $typeName = '微信小程序';
  13. protected $typeTempalte = '-wxapp';
  14. protected $typeSign = WXAPP_TYPE_SIGN;
  15. protected $supportVersion = STATUS_ON;
  16. protected function getAccountInfo($acid) {
  17. $account = table('account_wxapp')->getAccount($acid);
  18. $account['encrypt_key'] = $account['key'];
  19. return $account;
  20. }
  21. public function getOauthInfo($code = '') {
  22. global $_W, $_GPC;
  23. if (!empty($_GPC['code'])) {
  24. $code = $_GPC['code'];
  25. }
  26. $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$this->account['key']}&secret={$this->account['secret']}&js_code={$code}&grant_type=authorization_code";
  27. return $response = $this->requestApi($url);
  28. }
  29. public function getOauthCodeUrl($callback, $state = '') {
  30. return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->account['key']}&redirect_uri={$callback}&response_type=code&scope=snsapi_base&state={$state}#wechat_redirect";
  31. }
  32. public function getOauthUserInfoUrl($callback, $state = '') {
  33. return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->account['key']}&redirect_uri={$callback}&response_type=code&scope=snsapi_userinfo&state={$state}#wechat_redirect";
  34. }
  35. public function checkSign() {
  36. $token = $this->account['token'];
  37. $signkey = array($token, $_GET['timestamp'], $_GET['nonce']);
  38. sort($signkey, SORT_STRING);
  39. $signString = implode($signkey);
  40. $signString = sha1($signString);
  41. return $signString == $_GET['signature'];
  42. }
  43. public function pkcs7Encode($encrypt_data, $iv) {
  44. $key = base64_decode($_SESSION['session_key']);
  45. $result = aes_pkcs7_decode($encrypt_data, $key, $iv);
  46. if (is_error($result)) {
  47. return error(1, '解密失败');
  48. }
  49. $result = json_decode($result, true);
  50. if (empty($result)) {
  51. return error(1, '解密失败');
  52. }
  53. if ($result['watermark']['appid'] != $this->account['key']) {
  54. return error(1, '解密失败');
  55. }
  56. unset($result['watermark']);
  57. return $result;
  58. }
  59. public function checkIntoManage() {
  60. global $_GPC;
  61. if (empty($this->account) || (!empty($this->uniaccount['account']) && $this->uniaccount['account'] != ACCOUNT_TYPE_APP_NORMAL && !defined('IN_MODULE')) || empty($_GPC['version_id'])) {
  62. return false;
  63. }
  64. return true;
  65. }
  66. public function getAccessToken() {
  67. $cachekey = cache_system_key('accesstoken_key', array('key' => $this->account['key']));
  68. $cache = cache_load($cachekey);
  69. if (!empty($cache) && !empty($cache['token']) && $cache['expire'] > TIMESTAMP) {
  70. $this->account['access_token'] = $cache;
  71. return $cache['token'];
  72. }
  73. if (empty($this->account['key']) || empty($this->account['secret'])) {
  74. return error('-1', '未填写小程序的 appid 或 appsecret!');
  75. }
  76. $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->account['key']}&secret={$this->account['secret']}";
  77. $response = $this->requestApi($url);
  78. $record = array();
  79. $record['token'] = $response['access_token'];
  80. $record['expire'] = TIMESTAMP + $response['expires_in'] - 200;
  81. $this->account['access_token'] = $record;
  82. cache_write($cachekey, $record);
  83. return $record['token'];
  84. }
  85. public function getJssdkConfig($url = ''){
  86. return array();
  87. }
  88. public function getCodeLimit($path, $width = '430', $option = array()) {
  89. if (!preg_match('/[0-9a-zA-Z\&\/\:\=\?\-\.\_\~\@]{1,128}/', $path)) {
  90. return error(1, '路径值不合法');
  91. }
  92. $access_token = $this->getAccessToken();
  93. if(is_error($access_token)){
  94. return $access_token;
  95. }
  96. $data = array(
  97. 'path' => $path,
  98. 'width' => intval($width),
  99. );
  100. if (!empty($option['auto_color'])) {
  101. $data['auto_color'] = intval($option['auto_color']);
  102. }
  103. if (!empty($option['line_color'])) {
  104. $data['line_color'] = array(
  105. 'r' => $option['line_color']['r'],
  106. 'g' => $option['line_color']['g'],
  107. 'b' => $option['line_color']['b'],
  108. );
  109. $data['auto_color'] = false;
  110. }
  111. $url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" . $access_token;
  112. $response = $this->requestApi($url, json_encode($data));
  113. if (is_error($response)) {
  114. return $response;
  115. }
  116. return $response['content'];
  117. }
  118. public function getCodeUnlimit($scene, $page = '', $width = '430', $option = array()) {
  119. if (!preg_match('/[0-9a-zA-Z\!\#\$\&\'\(\)\*\+\,\/\:\;\=\?\@\-\.\_\~]{1,32}/', $scene)) {
  120. return error(1, '场景值不合法');
  121. }
  122. $access_token = $this->getAccessToken();
  123. if(is_error($access_token)){
  124. return $access_token;
  125. }
  126. $data = array(
  127. 'scene' => $scene,
  128. 'width' => intval($width),
  129. );
  130. if (!empty($page)) {
  131. $data['page'] = $page;
  132. }
  133. if (!empty($option['auto_color'])) {
  134. $data['auto_color'] = intval($option['auto_color']);
  135. }
  136. if (!empty($option['line_color'])) {
  137. $data['line_color'] = array(
  138. 'r' => $option['line_color']['r'],
  139. 'g' => $option['line_color']['g'],
  140. 'b' => $option['line_color']['b'],
  141. );
  142. $data['auto_color'] = false;
  143. }
  144. $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token;
  145. $response = $this->requestApi($url, json_encode($data));
  146. if (is_error($response)) {
  147. return $response;
  148. }
  149. return $response['content'];
  150. }
  151. public function getQrcode() {
  152. }
  153. public function errorCode($code, $errmsg = '未知错误') {
  154. $errors = array(
  155. '-1' => '系统繁忙',
  156. '0' => '请求成功',
  157. '40001' => '获取access_token时AppSecret错误,或者access_token无效',
  158. '40002' => '不合法的凭证类型',
  159. '40003' => '不合法的OpenID',
  160. '40004' => '不合法的媒体文件类型',
  161. '40005' => '不合法的文件类型',
  162. '40006' => '不合法的文件大小',
  163. '40007' => '不合法的媒体文件id',
  164. '40008' => '不合法的消息类型',
  165. '40009' => '不合法的图片文件大小',
  166. '40010' => '不合法的语音文件大小',
  167. '40011' => '不合法的视频文件大小',
  168. '40012' => '不合法的缩略图文件大小',
  169. '40013' => '不合法的APPID',
  170. '40014' => '不合法的access_token',
  171. '40015' => '不合法的菜单类型',
  172. '40016' => '不合法的按钮个数',
  173. '40017' => '不合法的按钮个数',
  174. '40018' => '不合法的按钮名字长度',
  175. '40019' => '不合法的按钮KEY长度',
  176. '40020' => '不合法的按钮URL长度',
  177. '40021' => '不合法的菜单版本号',
  178. '40022' => '不合法的子菜单级数',
  179. '40023' => '不合法的子菜单按钮个数',
  180. '40024' => '不合法的子菜单按钮类型',
  181. '40025' => '不合法的子菜单按钮名字长度',
  182. '40026' => '不合法的子菜单按钮KEY长度',
  183. '40027' => '不合法的子菜单按钮URL长度',
  184. '40028' => '不合法的自定义菜单使用用户',
  185. '40029' => '不合法的oauth_code',
  186. '40030' => '不合法的refresh_token',
  187. '40031' => '不合法的openid列表',
  188. '40032' => '不合法的openid列表长度',
  189. '40033' => '不合法的请求字符,不能包含\uxxxx格式的字符',
  190. '40035' => '不合法的参数',
  191. '40038' => '不合法的请求格式',
  192. '40039' => '不合法的URL长度',
  193. '40050' => '不合法的分组id',
  194. '40051' => '分组名字不合法',
  195. '41001' => '缺少access_token参数',
  196. '41002' => '缺少appid参数',
  197. '41003' => '缺少refresh_token参数',
  198. '41004' => '缺少secret参数',
  199. '41005' => '缺少多媒体文件数据',
  200. '41006' => '缺少media_id参数',
  201. '41007' => '缺少子菜单数据',
  202. '41008' => '缺少oauth code',
  203. '41009' => '缺少openid',
  204. '42001' => 'access_token超时',
  205. '42002' => 'refresh_token超时',
  206. '42003' => 'oauth_code超时',
  207. '43001' => '需要GET请求',
  208. '43002' => '需要POST请求',
  209. '43003' => '需要HTTPS请求',
  210. '43004' => '需要接收者关注',
  211. '43005' => '需要好友关系',
  212. '44001' => '多媒体文件为空',
  213. '44002' => 'POST的数据包为空',
  214. '44003' => '图文消息内容为空',
  215. '44004' => '文本消息内容为空',
  216. '45001' => '多媒体文件大小超过限制',
  217. '45002' => '消息内容超过限制',
  218. '45003' => '标题字段超过限制',
  219. '45004' => '描述字段超过限制',
  220. '45005' => '链接字段超过限制',
  221. '45006' => '图片链接字段超过限制',
  222. '45007' => '语音播放时间超过限制',
  223. '45008' => '图文消息超过限制',
  224. '45009' => '接口调用超过限制',
  225. '45010' => '创建菜单个数超过限制',
  226. '45015' => '回复时间超过限制',
  227. '45016' => '系统分组,不允许修改',
  228. '45017' => '分组名字过长',
  229. '45018' => '分组数量超过上限',
  230. '45056' => '创建的标签数过多,请注意不能超过100个',
  231. '45057' => '该标签下粉丝数超过10w,不允许直接删除',
  232. '45058' => '不能修改0/1/2这三个系统默认保留的标签',
  233. '45059' => '有粉丝身上的标签数已经超过限制',
  234. '45157' => '标签名非法,请注意不能和其他标签重名',
  235. '45158' => '标签名长度超过30个字节',
  236. '45159' => '非法的标签',
  237. '46001' => '不存在媒体数据',
  238. '46002' => '不存在的菜单版本',
  239. '46003' => '不存在的菜单数据',
  240. '46004' => '不存在的用户',
  241. '47001' => '解析JSON/XML内容错误',
  242. '48001' => 'api功能未授权',
  243. '50001' => '用户未授权该api',
  244. '40070' => '基本信息baseinfo中填写的库存信息SKU不合法。',
  245. '41011' => '必填字段不完整或不合法,参考相应接口。',
  246. '40056' => '无效code,请确认code长度在20个字符以内,且处于非异常状态(转赠、删除)。',
  247. '43009' => '无自定义SN权限,请参考开发者必读中的流程开通权限。',
  248. '43010' => '无储值权限,请参考开发者必读中的流程开通权限。',
  249. '43011' => '无积分权限,请参考开发者必读中的流程开通权限。',
  250. '40078' => '无效卡券,未通过审核,已被置为失效。',
  251. '40079' => '基本信息base_info中填写的date_info不合法或核销卡券未到生效时间。',
  252. '45021' => '文本字段超过长度限制,请参考相应字段说明。',
  253. '40080' => '卡券扩展信息cardext不合法。',
  254. '40097' => '基本信息base_info中填写的参数不合法。',
  255. '49004' => '签名错误。',
  256. '43012' => '无自定义cell跳转外链权限,请参考开发者必读中的申请流程开通权限。',
  257. '40099' => '该code已被核销。',
  258. '61005' => '缺少接入平台关键数据,等待微信开放平台推送数据,请十分钟后再试或是检查“授权事件接收URL”是否写错(index.php?c=account&amp;a=auth&amp;do=ticket地址中的&amp;符号容易被替换成&amp;amp;)',
  259. '61023' => '请重新授权接入该公众号',
  260. );
  261. $code = strval($code);
  262. if($errors[$code]) {
  263. return $errors[$code];
  264. } else {
  265. return $errmsg;
  266. }
  267. }
  268. protected function requestApi($url, $post = '') {
  269. $response = ihttp_request($url, $post);
  270. $result = @json_decode($response['content'], true);
  271. if(is_error($response)) {
  272. return error($result['errcode'], "访问公众平台接口失败, 错误详情: {$this->errorCode($result['errcode'])}");
  273. }
  274. if(empty($result)) {
  275. return $response;
  276. } elseif(!empty($result['errcode'])) {
  277. return error($result['errcode'], "访问公众平台接口失败, 错误: {$result['errmsg']},错误详情:{$this->errorCode($result['errcode'])}");
  278. }
  279. return $result;
  280. }
  281. public function result($errno, $message = '', $data = '') {
  282. exit(json_encode(array(
  283. 'errno' => $errno,
  284. 'message' => $message,
  285. 'data' => $data,
  286. )));
  287. }
  288. public function getDailyVisitTrend($date) {
  289. global $_W;
  290. $token = $this->getAccessToken();
  291. if (is_error($token)) {
  292. return $token;
  293. }
  294. $url = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token={$token}";
  295. $data = array(
  296. 'begin_date' => $date,
  297. 'end_date' => $date
  298. );
  299. $response = $this->requestApi($url, json_encode($data));
  300. if (is_error($response)) {
  301. return $response;
  302. }
  303. return $response['list'][0];
  304. }
  305. }