Forráskód Böngészése

1.整理、清理 Wechatext、Wechatauth、Snoopy及对应示例至old_version目录
2.公众号类 恢复 生成随机字串 方法(JS后端会用到)
3.修改wiki及README文档
4.企业号类 增加 邀请成员关注 方法
5.test目录增加新版JSAPI调用demo

binsee 10 éve
szülő
commit
de056e408c

+ 98 - 54
README.md

@@ -19,13 +19,13 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
 
 ## 目录 
 > **[wechat.class.php 官方API类库](#user-content-1-wechatclassphp-官方api类库)**  
-> **[wechatext.class.php 非官方扩展API](#user-content-2-wechatextclassphp-非官方扩展api)**  
-> **[wechatauth.class.php 授权登陆](#user-content-3-wechatauthclassphp-授权登陆)**  
-> **[wechat.js 内嵌JS](#user-content-4-wechatjs-内嵌js)**  
-> **[errCode.php 全局返回码类](#user-content-5-errcodephp-全局返回码类)**  
 > **[qywechat.class.php 企业号API类库](#user-content-6-qywechatclassphp-企业号api类库)**  
+> **[errCode.php|qyerrCode.php 全局返回码类](#user-content-5-errcodephp-全局返回码类)**  
+> **[old_version/wechatpay.class.php 旧版微信支付V2接口类库](#user-content-7-wechatpayclassphp-旧版微信支付V2接口类库)**  
+> ~~**[old_version/wechatext.class.php 非官方扩展API(停止维护)](#user-content-2-wechatextclassphp-非官方扩展api)**~~  
+> ~~**[old_version/wechatauth.class.php 授权登陆(停止维护)](#user-content-3-wechatauthclassphp-授权登陆)**~~  
+> ~~**[old_version/wechat.js 内嵌JS(已废弃)](#user-content-4-wechatjs-内嵌js)**~~  
 > **[调用示例](#user-content-调用示例)**  
-
 ----------
 
 ## 1. wechat.class.php 官方API类库
@@ -43,17 +43,12 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
 - 用户信息(查询用户基本信息、获取关注者列表) **(认证权限)**
 - 多客服功能(客服管理、获取客服记录、客服会话管理) **(认证权限)**
 - 媒体文件(上传、获取) **(认证权限)**
-- 调用地址组件 **(支付权限)**
-- 生成订单签名数据 **(支付权限)**
-- 订单成功回调 **(支付权限)**
-- 发货通知 **(支付权限)**
-- 支付订单查询 **(支付权限)**
 - 高级群发 **(认证权限)**
 - 模板消息(设置所属行业、添加模板、发送模板消息) **(服务号、认证权限)**
 - 卡券管理(创建、修改、删除、发放、门店管理等) **(认证权限)**
 - 语义理解 **(服务号、认证权限)**
 - 获取微信服务器IP列表 **(初级权限)**  
-- 微信JSAPI授权(获取ticket、获取签名) **(初级权限`暂未确定`)**
+- 微信JSAPI授权(获取ticket、获取签名) **(初级权限)**
 > 备注:  
 > 初级权限:基本权限,任何正常的公众号都有此权限  
 > 菜单权限:正常的服务号、认证后的订阅号拥有此权限  
@@ -67,10 +62,7 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
 	'token'=>'tokenaccesskey', //填写你设定的key
 	'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey
 	'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询
-	'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
-	'partnerid'=>'88888888', //财付通商户身份标识,支付权限专用,没有可不填
-	'partnerkey'=>'', //财付通商户权限密钥Key,支付权限专用
-	'paysignkey'=>'' //商户签名密钥Key,支付权限专用
+	'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥
 	);
  $weObj = new Wechat($options); //创建实例对象
  //TODO:调用$weObj各实例方法
@@ -193,13 +185,7 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
  *  getOauthUserinfo($access_token,$openid) 通过网页授权的access_token获取用户资料  
  *  getOauthAuth($access_token,$openid)  检验授权凭证access_token是否有效
  *  getSignature($arrdata,'sha1') 生成签名字串  
- *  generateNonceStr($length) 获取随机字串  
- *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type="WX",$input_charset="UTF-8",$time_start="",$time_expire="",$transport_fee="",$product_fee="",$goods_tag="",$attach="") 生成订单package字符串  
- *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  
- *  checkOrderSignature($orderxml='') 回调通知签名验证  
- *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  
- *  getPayOrder($out_trade_no) 查询订单信息  
- *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名
+ *  generateNonceStr($length=16) 获取随机字串  
  *  setTMIndustry($id1,$id2='') 模板消息,设置所属行业
  *  addTemplateMessage($tpl_id) 模板消息,添加消息模板
  *  sendTemplateMessage($data) 发送模板消息
@@ -238,7 +224,8 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
  *  setCardTestWhiteList($openid=array(),$user=array()) 设置卡券测试白名单
  
  
-## 2. wechatext.class.php 非官方扩展API  
+## ~~2. wechatext.class.php 非官方扩展API~~  
+**此扩展类库已经不再更新,原因是官方对公众号开放了众多接口,此类库继续维护的意义不大**
 非官方扩展API,需要配置公众平台账户和密码,能实现对已关注用户的点对点微信,此方式不保证长期有效。  
 类方法里提及的用户id在接口返回结构里表述为FakeId, 属同一概念, 在下面wechatauth类里则表示为Uin, 用户id对应的微信号必须通过getInfo()方法通过返回数组的Username值获取, 但非关注关系用户资料不能获取.  
 调用下列方法前必须经过login()方法和checkValid()验证方法才能获得调用权限. 有的账户无法通过登陆可能因为要求提供验证码, 可以手动登陆后把获取到的cookie写进程序存放cookie的文件解决.  
@@ -263,7 +250,8 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
  *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据  
  *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据  
 
-## 3. wechatauth.class.php 授权登陆
+## ~~3. wechatauth.class.php 授权登陆~~
+**此扩展类库已经不再更新,原因是官方开放平台对网站应用开放的有授权登陆接口,更标准,更好用。请查看:[微信开放平台](http://open.weixin.qq.com)**
 通过微信二维码登陆微信的API, 能实现第三方网站同步登陆, 首先程序分别通过get_login_code和get_code_image方法获取授权二维码图片, 然后利用微信手机客户端扫描二维码图片后将自动跳出授权页面, 用户点击授权后即可获取对应的用户资料和头像信息. 详细验证步骤请看test3.php例子.   
 ### 类主要方法:
  *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码  
@@ -273,7 +261,8 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
  *  get_avatar($url) 获取用户头像图片数据  
  *  logout() 注销登陆  
 
-## 4. wechat.js 内嵌JS
+## ~~4. wechat.js 内嵌JS~~
+**此JS脚本已经废弃不再更新,原因是官方在微信6.0.2版本开放了全新的JSAPI接口,更全面好用。请查看:[微信公众平台WIKI](http://mp.weixin.qq.com/wiki)**
 ### 微信内嵌网页特殊功能js调用:
  * WeixinJS.hideOptionMenu() 隐藏右上角按钮
  * WeixinJS.showOptionMenu() 显示右上角按钮
@@ -306,6 +295,8 @@ https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN
 
 ## 5. errCode.php 全局返回码类
 当调用API接口失败时,可以用此类来换取失败原因的中文说明。
+注意:微信公众号引用`errCode.php`,企业号引用`qyerrCode.php`。
+
 ### 使用方法:
 ```php
 include "errCode.php";  //或 qyerrCode.php
@@ -435,6 +426,7 @@ $options = array(
 > 0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加
 * getUserListInfo($department_id,$fetch_child=0,$status=0) 获取部门成员详情,参数同上
 * getUserId($code,$agentid) 根据code获取员工UserID与手机设备号,参数:Oauth2.0或者二次验证返回的code值,跳转链接时所在的企业应用ID
+* sendInvite($userid,$invite_tips='') 邀请成员关注
 * createTag($data) 创建标签,参数:array("tagname" => "UI")
 * updateTag($data) 更新标签,参数:array("tagid" => "1","tagname" => "UI")
 * deleteTag($tagid) 删除标签,参数:标签TagID
@@ -446,6 +438,54 @@ $options = array(
 * authSucc($userid) 二次验证,参数: 员工UserID
 * getOauthRedirect($callback,$state='STATE',$scope='snsapi_base') 组合授权跳转接口url
 
+
+## 7. wechatpay.class.php 旧版微信支付V2接口类库
+旧版微信支付类库(微信支付V2),已移动至old_version目录下。
+自2014年8月开始申请到的微信支付都是V3接口,据官方说V2的会陆续升级为V3接口,但时间及升级渠道未确认。
+
+### 主要功能 
+- 获取access_token **(初级权限)**
+- 调用地址组件 **(支付权限)**
+- 生成订单签名数据 **(支付权限)**
+- 订单成功回调 **(支付权限)**
+- 发货通知 **(支付权限)**
+- 支付订单查询 **(支付权限)**
+> 备注:  
+> 初级权限:基本权限,任何正常的公众号都有此权限  
+> 菜单权限:正常的服务号、认证后的订阅号拥有此权限  
+> 认证权限:分为订阅号、服务号认证,如前缀服务号则仅认证的服务号有此权限,否则为认证后的订阅号、服务号都有此权限  
+> 支付权限:仅认证后的服务号可以申请此权限  
+
+
+### 初始化动作 
+```php
+ $options = array(
+	'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询
+	'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
+	'partnerid'=>'88888888', //财付通商户身份标识,支付权限专用,没有可不填
+	'partnerkey'=>'', //财付通商户权限密钥Key,支付权限专用
+	'paysignkey'=>'' //商户签名密钥Key,支付权限专用
+	);
+ $weObj = new Wechat($options); //创建实例对象
+ //TODO:调用$weObj各实例方法
+```
+
+### 主动接口方法:   
+ *  checkAuth($appid='',$appsecret='',$token='') 获取access_token。可根据appid和appsecret获取,或手动指定access_token
+ *  resetAuth($appid='') 删除验证数据
+ *  getSignature($arrdata,'sha1') 生成签名字串  
+ *  generateNonceStr($length=16) 获取随机字串  
+ *  createNativeUrl($productid) 生成原生支付url
+ *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type="WX",$input_charset="UTF-8",$time_start="",$time_expire="",$transport_fee="",$product_fee="",$goods_tag="",$attach="") 生成订单package字符串  
+ *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  
+ *  checkOrderSignature($orderxml='') 回调通知签名验证  
+ *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  
+ *  getPayOrder($out_trade_no) 查询订单信息  
+ *  setUserToken($user_token) 设置用户授权密钥
+ *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名
+
+
+
 # 调用示例
 ----------
 
@@ -454,7 +494,8 @@ $options = array(
 //test1.php
 include "wechat.class.php";
 $options = array(
-		'token'=>'tokenaccesskey' //填写你设定的key
+		'token'=>'tokenaccesskey', //填写你设定的key
+        'encodingaeskey'=>'encodingaeskey' //填写加密用的EncodingAESKey,如接口为明文模式可忽略
 	);
 $weObj = new Wechat($options);
 $weObj->valid();//明文或兼容模式可以在接口验证通过后注释此句,但加密模式一定不能注释,否则会验证失败
@@ -473,9 +514,35 @@ switch($type) {
 }
 ```
 
+## 企业号API类库调用示例:
+可参考**test**目录下的**qydemo.php**
+```php
+include "wechat.class.php";
+$options = array(
+        'token'=>'9Ixxxxxxx',	//填写应用接口的Token
+        'encodingaeskey'=>'d4o9WVg8sxxxxxxxxxxxxxxxxxxxxxx',//填写加密用的EncodingAESKey
+        'appid'=>'wxa07979baxxxxxxxx',	//填写高级调用功能的appid
+);
+$weObj = new Wechat($options);
+$weObj->valid(); //注意, 企业号与普通公众号不同,必须打开验证,不要注释掉
+$type = $weObj->getRev()->getRevType();
+switch($type) {
+	case Wechat::MSGTYPE_TEXT:
+			$weObj->text("hello, I'm wechat")->reply();
+			exit;
+			break;
+	case Wechat::MSGTYPE_EVENT:
+			break;
+	case Wechat::MSGTYPE_IMAGE:
+			break;
+	default:
+			$weObj->text("help info")->reply();
+}
+```
+
 ## 扩展包Wechatext调用示例: 
 ```php
-//test2.php 
+// old_version/test/test2.php 
 	include "wechatext.class.php";
 	
 	function logdebug($text){
@@ -505,7 +572,7 @@ switch($type) {
 
 ## 微信二维码Wechatauth登陆示例: 
 ```php
-//test3.php
+// old_version/test/test3.php
 	include "../wechatauth.class.php";
 	session_start();
 	$sid  = session_id();
@@ -533,33 +600,10 @@ switch($type) {
 	$logincode =  $wechat->get_login_code(); //获取授权码
 	$qrimg = $wechat->get_code_image(); //待输出的二维码图片
 ```
-HTML部分请看test/test3.php, 主要是定时ajax查询是否已经授权成功
+HTML部分请看old_version/test/test3.php, 主要是定时ajax查询是否已经授权成功
 
-## 企业号API类库调用示例:
-可参考**test**目录下的**qydemo.php**
-```php
-include "wechat.class.php";
-$options = array(
-        'token'=>'9Ixxxxxxx',	//填写应用接口的Token
-        'encodingaeskey'=>'d4o9WVg8sxxxxxxxxxxxxxxxxxxxxxx',//填写加密用的EncodingAESKey
-        'appid'=>'wxa07979baxxxxxxxx',	//填写高级调用功能的appid
-);
-$weObj = new Wechat($options);
-$weObj->valid(); //注意, 企业号与普通公众号不同,必须打开验证,不要注释掉
-$type = $weObj->getRev()->getRevType();
-switch($type) {
-	case Wechat::MSGTYPE_TEXT:
-			$weObj->text("hello, I'm wechat")->reply();
-			exit;
-			break;
-	case Wechat::MSGTYPE_EVENT:
-			break;
-	case Wechat::MSGTYPE_IMAGE:
-			break;
-	default:
-			$weObj->text("help info")->reply();
-}
-```
+## 新版微信JSAPI调用DEMO: 
+请看test/jsapi目录
 
 License
 -------

+ 22 - 6
Thinkphp/Wechat.class.php

@@ -1075,9 +1075,9 @@ class Wechat
 	}
 
 	/**
-	 * 通用auth验证方法,获取access_token
-	 * @param string $appid
-	 * @param string $appsecret
+	 * 获取access_token
+	 * @param string $appid 如在类初始化时已提供,则可为空
+	 * @param string $appsecret 如在类初始化时已提供,则可为空
 	 * @param string $token 手动指定access_token,非必要情况不建议用
 	 */
 	public function checkAuth($appid='',$appsecret='',$token=''){
@@ -1236,7 +1236,7 @@ class Wechat
 			return '[' . $json . ']'; //Return numerical JSON
 		return '{' . $json . '}'; //Return associative JSON
 	}
-	
+
 	/**
 	 * 获取签名
 	 * @param array $arrdata 签名数组
@@ -1254,8 +1254,24 @@ class Wechat
 			else
 				$paramstring .= "&" . $key . "=" . $value;
 		}
-		$paySign = $method($paramstring);
-		return $paySign;
+		$Sign = $method($paramstring);
+		return $Sign;
+	}
+
+	/**
+	 * 生成随机字串
+	 * @param number $length 长度,默认为16,最长为32字节
+	 * @return string
+	 */
+	public function generateNonceStr($length=16){
+		// 密码字符集,可任意添加你需要的字符
+		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+		$str = "";
+		for($i = 0; $i < $length; $i++)
+		{
+			$str .= $chars[mt_rand(0, strlen($chars) - 1)];
+		}
+		return $str;
 	}
 
 	/**

+ 0 - 267
Thinkphp/Wechatauth.class.php

@@ -1,267 +0,0 @@
-<?php
-/**
- *	微信公众平台PHP-SDK
- *  Wechatauth为非官方微信登陆API
- *  用户通过扫描网页提供的二维码实现登陆信息获取
- *  主要实现如下功能:
- *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
- *  get_code_image($code='') 将上面获取的授权码转换为图片二维码
- *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
- *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息
- *  get_avatar($url) 获取用户头像图片数据
- *  @author dodge <dodgepudding@gmail.com>
- *  @link https://github.com/dodgepudding/wechat-php-sdk
- *  @version 1.1
- *  
- */
-include "Snoopy.class.php";
-class Wechatauth
-{
-	private $cookie;
-	private $skey;
-	private $_cookiename;
-	private $_cookieexpired = 3600;
-	private $_account = 'test';
-	private $_datapath = './data/cookie_';
-	private $debug;
-	private $_logcallback;
-	public $login_user; //当前登陆用户, 调用get_login_info后获取
-	
-	public function __construct($options)
-	{
-		$this->_account = isset($options['account'])?$options['account']:'';
-		$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
-		$this->debug = isset($options['debug'])?$options['debug']:false;
-		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
-		$this->_cookiename = $this->_datapath.$this->_account;
-		$this->getCookie($this->_cookiename);
-	}
-	/**
-	 * 把cookie写入缓存
-	 * @param  string $filename 缓存文件名
-	 * @param  string $content  文件内容
-	 * @return bool
-	 */
-	public function saveCookie($filename,$content){
-		return S($filename,$content,$this->_cookieexpired);
-	}
-
-	/**
-	 * 读取cookie缓存内容
-	 * @param  string $filename 缓存文件名
-	 * @return string cookie
-	 */
-	public function getCookie($filename){
-		$data = S($filename);
-		if ($data) $this->cookie = $data;
-		return $this->cookie;
-	}
-	
-	/*
-	 * 删除cookie
-	 */
-	public function deleteCookie($filename) {
-		$this->cookie = '';
-		S($filename,null);
-		return true;
-	}
-	
-	private function log($log){
-		if ($this->debug && function_exists($this->_logcallback)) {
-			if (is_array($log)) $log = print_r($log,true);
-			return call_user_func($this->_logcallback,$log);
-		}
-	}
-	
-	/**
-	 * 获取登陆二维码对应的授权码
-	 */	
-	public function get_login_code(){
-		if ($this->_logincode) return $this->_logincode;
-		$t = time().strval(mt_rand(100,999));
-		$codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->fetch($codeurl);
-		$result = $send_snoopy->results;
-		if ($result) {
-			preg_match("/window.QRLogin.uuid\s+=\s+\"([^\"]+)\"/",$result,$matches);
-			if(count($matches)>1) {
-				$this->_logincode = $matches[1];
-				$_SESSION['login_step'] = 0;
-				return $this->_logincode;
-			}
-		}
-		return $result;
-	}
-
-	/**
-	 * 通过授权码获取对应的二维码图片地址
-	 * @param string $code
-	 * @return string image url
-	 */
-	public function get_code_image($code=''){
-		if ($code=='') $code = $this->_logincode;
-		if (!$code) return false;
-		return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
-	}
-	
-	/**
-	 * 设置二维码对应的授权码
-	 * @param string $code
-	 * @return class $this
-	 */
-	public  function set_login_code($code) {
-		$this->_logincode = $code;
-		return $this;
-	}
-	
-	/**
-	 * 二维码登陆验证
-	 *
-	 * @return status:
-	 * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
-	 * 201: just scaned but not confirm
-	 * 200: confirm then you can get user info
-	 */
-	public function verify_code() {
-		if (!$this->_logincode) return false;
-		$t = time().strval(mt_rand(100,999));
-
-			$url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=0&_='.$t;
-			$send_snoopy = new Snoopy; 
-			$send_snoopy->referer = "https://wx.qq.com/";
-			$send_snoopy->fetch($url);
-			$result = $send_snoopy->results;
-			$this->log('step1:'.$result);
-			if ($result) {
-				preg_match("/window\.code=(\d+)/",$result,$matches);
-				if(count($matches)>1) {
-					$status = intval($matches[1]);
-					if ($status==201) $_SESSION['login_step'] = 1;
-					if ($status==200) {
-						preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
-						preg_match("/window.redirect_uri=\"([^\"]+)\"/",$result,$matcheurl);
-						$this->log('step2:'.print_r($matches,true));
-						if (count($matcheurl)>1) {
-							$ticket = $matches[1];
-							$scan = $matches[2];
-							//$loginurl = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
-							$loginurl = str_replace("wx.qq.com", "wx2.qq.com", $matcheurl[1]).'&fun=old';
-							$urlpart = parse_url($loginurl);
-							$send_snoopy = new Snoopy; 
-							$send_snoopy->referer = "https://{$urlpart['host']}/cgi-bin/mmwebwx-bin/webwxindex?t=chat";
-							$send_snoopy->fetch($loginurl);
-							$result = $send_snoopy->results;
-							$xml = simplexml_load_string($result);
-							if ($xml->ret=="0") $this->skey = $xml->skey;
-							foreach ($send_snoopy->headers as $key => $value) {
-								$value = trim($value);
-								if(strpos($value,'Set-Cookie: ') !== false){
-									$tmp = str_replace("Set-Cookie: ","",$value);
-									$tmparray = explode(';', $tmp);
-									$item = trim($tmparray[0]);
-									$cookie.=$item.';';
-								}
-							}
-							$cookie .="Domain=.qq.com;";
-							$this->cookie = $cookie;
-							$this->log('step3:'.$loginurl.';cookie:'.$cookie.';respond:'.$result);
-							
-							$this->saveCookie($this->_cookiename,$this->cookie);
-						}
-					}
-					return $status;
-				}
-			}
-		return false;
-	}
-	
-	/**
-	 * 获取登陆的cookie
-	 *
-	 * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
-	 * @return string|array
-	 */
-	public function get_login_cookie($is_array = false){
-		if (!$is_array)	return $this->cookie;
-		$c_arr = explode(';',$this->cookie);
-		$cookie = array();
-		foreach($c_arr as $item) {
-			$kitem = explode('=',trim($item));
-			if (count($kitem)>1) {
-				$key = trim($kitem[0]);
-				$val = trim($kitem[1]);
-				if (!empty($val)) $cookie[$key] = $val;
-			}
-		}
-		return $cookie;
-	}
-	
-	/**
-	 * 	 授权登陆后获取用户登陆信息
-	 */
-	public function get_login_info(){
-		if (!$this->cookie) return false;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy = new Snoopy; 
-		$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t.'&skey='.urlencode($this->skey);
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$citems = $this->get_login_cookie(true);
-		$post = array(
-			"BaseRequest"=>array(
-				array(
-					"Uin"=>$citems['wxuin'],
-					"Sid"=>$citems['wxsid'],
-					"Skey"=>$this->skey,
-					"DeviceID"=>''
-				)
-			)
-		);
-		$send_snoopy->submit($submit,json_encode($post));
-		$this->log('login_info:'.$send_snoopy->results);
-		$result = json_decode($send_snoopy->results,true);
-		if ($result['BaseResponse']['Ret']<0) return false;
-		$this->_login_user = $result['User'];
-		return $result;
-	}
-	
-	/**
-	 *  获取头像
-	 *  @param string $url 传入从用户信息接口获取到的头像地址
-	 */
-	public function get_avatar($url) {
-		if (!$this->cookie) return false;
-		if (strpos($url, 'http')===false) {
-			$url = 'http://wx2.qq.com'.$url;
-		}
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		if ($result) 
-			return $result;
-		else
-			return false;
-	}
-	
-	/**
-	 * 登出当前登陆用户
-	 */
-	public function logout(){
-		if (!$this->cookie) return false;
-		preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
-		if (count($matches)>1) $uid = $matches[1];
-		preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
-		if (count($matches)>1) $sid = $matches[1];
-		$this->log('logout: uid='.$uid.';sid='.$sid);
-		$send_snoopy = new Snoopy; 
-		$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
-		$this->deleteCookie($this->_cookiename);
-		return true;
-	}
-}

+ 0 - 784
Thinkphp/Wechatext.class.php

@@ -1,784 +0,0 @@
-<?php
-/**
- *	微信公众平台PHP-SDK
- *  Wechatext为非官方微信发送API
- *  注: 用户id为通过getMsg()方法获取的FakeId值
- *  主要实现如下功能:
- *  send($id,$content) 向某用户id发送微信文字信息
- *  getUserList($page,$pagesize,$groupid) 获取用户信息
- *  getGroupList($page,$pagesize) 获取群组信息
- *  sendNews($id,$msgid) 发送图文消息
- *  getNewsList($page,$pagesize) 获取图文信息列表
- *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频
- *  addPreview($title,$author,$summary,$content,$photoid,$srcurl='')   创建新的图文信息 
- *  getFileList($type,$page,$pagesize) 获取素材库文件列表
- *  sendImage($id,$fid) 发送图片消息
- *  sendAudio($id,$fid) 发送音频消息
- *  sendVideo($id,$fid) 发送视频消息
- *  getInfo($id) 根据id获取用户资料
- *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目
- *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据
- *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数
- *  消息返回结构:  {"id":"消息id","type":"类型号(1为文字,2为图片,3为语音)","fileId":"0","hasReply":"0","fakeId":"用户uid","nickName":"昵称","dateTime":"时间戳","content":"文字内容"} 
- *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据
- *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据
- *  quickSetInterface($url, $token) 快速设置接口信息
- *  @author dodge <dodgepudding@gmail.com>
- *  @link https://github.com/dodgepudding/wechat-php-sdk
- *  @version 1.2
- *  
- */
-
-include "Snoopy.class.php";
-class Wechatext
-{
-	private $cookie;
-	private $_cookiename;
-	private $_cookieexpired = 3600;
-	private $_account;
-	private $_password;
-	private $_datapath = './data/cookie_';
-	private $debug;
-	private $_logcallback;
-	private $_token;
-	
-	public function __construct($options)
-	{
-		$this->_account = isset($options['account'])?$options['account']:'';
-		$this->_password = isset($options['password'])?$options['password']:'';
-		$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
-		$this->debug = isset($options['debug'])?$options['debug']:false;
-		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
-		$this->_cookiename = $this->_datapath.$this->_account;
-		$this->cookie = $this->getCookie($this->_cookiename);
-	}
-
-	/**
-	 * 主动发消息
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $content 发送的内容
-	 */
-	public function send($id,$content)
-	{
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = 1;
-		$post['token'] = $this->_token;
-		$post['content'] = $content;
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$id&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 群发功能 纯文本
-	 * @param string $content
-	 * @return string
-	 */
-	public function mass($content) {
-		$send_snoopy = new Snoopy;
-		$post = array();
-		$post['type'] = 1;
-		$post['token'] = $this->_token;
-		$post['content'] = $content;
-		$post['ajax'] = 1;
-		$post['city']='';
-		$post['country']='';
-		$post['f']='json';
-		$post['groupid']='-1';
-		$post['imgcode']='';
-		$post['lang']='zh_CN';
-		$post['province']='';
-		$post['random']=  rand(0, 1);
-		$post['sex']=0;
-		$post['synctxnews']=0;
-		$post['synctxweibo']=0;
-		$post['t']='ajax-response';
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/masssend";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 群发功能 图文素材
-	 * @param int $appmsgid 图文素材ID
-	 * @return string
-	 */
-	function massNews($appmsgid){
-		$send_snoopy = new Snoopy;
-		$post = array();
-		$post['type'] = 10;
-		$post['token'] = $this->_token;
-		$post['appmsgid'] = $appmsgid;
-		$post['ajax'] = 1;
-		$post['city']='';
-		$post['country']='';
-		$post['f']='json';
-		$post['groupid']='-1';
-		$post['imgcode']='';
-		$post['lang']='zh_CN';
-		$post['province']='';
-		$post['random']=  rand(0, 1);
-		$post['sex']=0;
-		$post['synctxnews']=0;
-		$post['synctxweibo']=0;
-		$post['t']='ajax-response';
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/masssend";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 获取用户列表列表
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @param $groupid 分组id
-	 * @return array ({contacts:[{id:12345667,nick_name:"昵称",remark_name:"备注名",group_id:0},{}....]})
-	 */
-	function getUserList($page=0,$pagesize=10,$groupid=0){
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=".$pagesize."&pageidx=".$page."&type=0&groupid=0&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=".$pagesize."&pageidx=".$page."&type=0&groupid=$groupid&lang=zh_CN&f=json&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('userlist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['contact_list'])) {
-			$json = json_decode($json['contact_list'],true);
-			if (isset($json['contacts']))
-				return $json['contacts'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取分组列表
-	 * 
-	 */
-	function getGroupList(){
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&f=json&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('userlist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['group_list'])){
-			$json = json_decode($json['group_list'],true);
-			if (isset($json['groups']))
-				return $json['groups'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取图文信息列表
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @return array
-	 */
-	public function getNewsList($page,$pagesize=10) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$type=10;
-		$begin = $page*$pagesize;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/appmsg?token=".$this->_token."&lang=zh_CN&type=$type&action=list&begin=$begin&count=$pagesize&f=json&random=0.".$t;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('newslist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['app_msg_info'])) {
-			return $json['app_msg_info'];
-		} 
-		return false;
-	}
-	
-	/**
-	 * 获取与指定用户的对话内容
-	 * @param  $fakeid
-	 * @return  array
-	 */
-	public function getDialogMsg($fakeid) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=".$fakeid."&token=".$this->_token."&lang=zh_CN&f=json&random=".$t;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('DialogMsg:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['page_info'])) {
-			return $json['page_info'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 发送图文信息,必须从图文库里选取消息ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $msgid 图文消息id
-	 */
-	public function sendNews($id,$msgid)
-	{
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = 10;
-		$post['token'] = $this->_token;
-		$post['fid'] = $msgid;
-		$post['appmsgid'] = $msgid;
-		$post['error'] = 'false';
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 上传附件(图片/音频/视频)
-	 * @param string $filepath 本地文件地址
-	 * @param int $type 文件类型: 2:图片 3:音频 4:视频
-	 */
-	public function uploadFile($filepath,$type=2) {
-		$send_snoopy = new Snoopy;
-		$send_snoopy->referer = "http://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-upload&lang=zh_CN&type=2&formId=1";
-		$t = time().strval(mt_rand(100,999));
-		$post = array('formId'=>'');
-		$postfile = array('uploadfile'=>$filepath);
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->set_submit_multipart();
-		$submit = "http://mp.weixin.qq.com/cgi-bin/uploadmaterial?cgi=uploadmaterial&type=$type&token=".$this->_token."&t=iframe-uploadfile&lang=zh_CN&formId=	file_from_".$t;
-		$send_snoopy->submit($submit,$post,$postfile);
-		$tmp = $send_snoopy->results;
-		$this->log('upload:'.$tmp);
-		preg_match("/formId,.*?\'(\d+)\'/",$tmp,$matches);
-		if (isset($matches[1])) {
-			return $matches[1];
-		}
-		return false;
-	}
-	
-	/**
-	 * 创建图文消息
-	 * @param array $title 标题
-	 * @param array $summary 摘要
-	 * @param array $content 内容
-	 * @param array $photoid 素材库里的图片id(可通过uploadFile上传后获取)
-	 * @param array $srcurl 原文链接
-	 * @return json
-	 */
-	public function addPreview($title,$author,$summary,$content,$photoid,$srcurl='') {
-		$send_snoopy = new Snoopy;
-		$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&token='.$this->_token;
-		
-		$submit = "https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&t=ajax-response&sub=create&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		
-		$send_snoopy->set_submit_normal();
-		$post = array(
-				'token'=>$this->_token,
-				'type'=>10,
-				'lang'=>'zh_CN',
-				'sub'=>'create',
-				'ajax'=>1,
-				'AppMsgId'=>'',				
-				'error'=>'false',
-		);
-		if (count($title)==count($author)&&count($title)==count($summary)&&count($title)==count($content)&&count($title)==count($photoid))
-		{
-			$i = 0;
-			foreach($title as $v) {
-				$post['title'.$i] = $title[$i];
-				$post['author'.$i] = $author[$i];
-				$post['digest'.$i] = $summary[$i];
-				$post['content'.$i] = $content[$i];
-				$post['fileid'.$i] = $photoid[$i];
-				if ($srcurl[$i]) $post['sourceurl'.$i] = $srcurl[$i];
-				
-				$i++;
-				}
-		}
-		$post['count'] = $i;
-		$post['token'] = $this->_token;
-		$send_snoopy->submit($submit,$post);
-		$tmp = $send_snoopy->results;
-		$this->log('step2:'.$tmp);
-		$json = json_decode($tmp,true);
-		return $json;
-	}
-	
-	/**
-	 * 发送媒体文件
-	 * @param $id 用户的uid(即FakeId)
-	 * @param $fid 文件id
-	 * @param $type 文件类型
-	 */
-	public function sendFile($id,$fid,$type) {
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = $type;
-		$post['token'] = $this->_token;
-		$post['fid'] = $fid;
-		$post['fileid'] = $fid;
-		$post['error'] = 'false';
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log('sendfile:'.$result);
-		$json = json_decode($result,true);
-		if ($json && $json['ret']==0) 
-			return true;
-		else
-			return false;
-	}
-	
-	/**
-	 * 获取素材库文件列表
-	 * @param $type 文件类型: 2:图片 3:音频 4:视频
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @return array
-	 */
-	public function getFileList($type,$page,$pagesize=10) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$begin = $page*$pagesize;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/filepage?token=".$this->_token."&lang=zh_CN&type=$type&random=0.".$t."&begin=$begin&count=$pagesize&f=json";
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('filelist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['page_info']))
-			return $json['page_info'];
-		else
-			return false;
-	}
-	
-	/**
-	 * 发送图文信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 文件id
-	 */
-	public function sendImage($id,$fid)
-	{
-		return $this->sendFile($id,$fid,2);
-	}
-	
-	/**
-	 * 发送语音信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 语音文件id
-	 */
-	public function sendAudio($id,$fid)
-	{
-		return $this->sendFile($id,$fid,3);
-	}
-	
-	/**
-	 * 发送视频信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 视频文件id
-	 */
-	public function sendVideo($id,$fid)
-	{
-		return $this->sendFile($id,$fid,4);
-	}
-	
-	/**
-	 * 发送预览图文消息
-	 * @param string $account 账户名称(user_name)
-	 * @param string $title 标题
-	 * @param string $summary 摘要
-	 * @param string $content 内容
-	 * @param string $photoid 素材库里的图片id(可通过uploadFile上传后获取)
-	 * @param string $srcurl 原文链接
-	 * @return json
-	 */
-	public function sendPreview($account,$title,$summary,$content,$photoid,$srcurl='') {
-		$send_snoopy = new Snoopy;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=preview&t=ajax-appmsg-preview";
-		$send_snoopy->set_submit_normal();
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&lang=zh_CN';
-		$post = array(
-				'AppMsgId'=>'',
-				'ajax'=>1,
-				'content0'=>$content,
-				'count'=>1,
-				'digest0'=>$summary,
-				'error'=>'false',
-				'fileid0'=>$photoid,
-				'preusername'=>$account,
-				'sourceurl0'=>$srcurl,
-				'title0'=>$title,
-		);
-		$post['token'] = $this->_token;
-		$send_snoopy->submit($submit,$post);
-		$tmp = $send_snoopy->results;
-		$this->log('sendpreview:'.$tmp);
-		$json = json_decode($tmp,true);
-		return $json;
-	}
-	
-	/**
-	 * 获取用户的信息
-	 * @param  string $id 用户的uid(即FakeId)
-	 * @return array  {fake_id:100001,nick_name:'昵称',user_name:'用户名',signature:'签名档',country:'中国',province:'广东',city:'广州',gender:'1',group_id:'0'},groups:{[id:0,name:'未分组',cnt:20]}
-	 */
-	public function getInfo($id)
-	{
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getcontactinfo";
-		$post = array('ajax'=>1,'lang'=>'zh_CN','random'=>'0.'.$t,'token'=>$this->_token,'t'=>'ajax-getcontactinfo','fakeid'=>$id);
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		$result = json_decode($send_snoopy->results,true);
-		if(isset($result['contact_info'])){
-			return $result['contact_info'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获得头像数据
-	 *
-	 * @param FakeId $fakeid
-	 * @return JPG二进制数据
-	 */
-	public function getHeadImg($fakeid){
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/misc/getheadimg?fakeid=$fakeid&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('Head image:'.$fakeid.'; length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-
-	/**
-	 * 获取消息更新数目
-	 * @param int $lastid 最近获取的消息ID,为0时获取总消息数目
-	 * @return int 数目
-	 */
-	public function getNewMsgNum($lastid=0){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getnewmsgnum?t=ajax-getmsgnum&lastmsgid=".$lastid;
-		$post = array('ajax'=>1,'token'=>$this->_token);
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		$result = json_decode($send_snoopy->results,1);
-		if(!$result){
-			return false;
-		}
-		return intval($result['newTotalMsgCount']);
-	}
-	
-	/**
-	 * 获取最新一条消息
-	 * @return array {"id":"最新一条id","type":"类型号(1为文字,2为图片,3为语音)","fileId":"0","hasReply":"0","fakeId":"用户uid","nickName":"昵称","dateTime":"时间戳","content":"文字内容","playLength":"0","length":"0","source":"","starred":"0","status":"4"}        
-	 */
-	public function getTopMsg(){
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$this->log($send_snoopy->results);
-		$result = $send_snoopy->results;
-		$json = json_decode($result,true);
-		if (isset($json['msg_items'])) {
-			$json = json_decode($json['msg_items'],true);
-			if(isset($json['msg_item']))
-				return array_shift($json['msg_item']);
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取新消息
-	 * @param $lastid 传入最后的消息id编号,为0则从最新一条起倒序获取
-	 * @param $offset lastid起算第一条的偏移量
-	 * @param $perpage 每页获取多少条
-	 * @param $day 最近几天消息(0:今天,1:昨天,2:前天,3:更早,7:五天内)
-	 * @param $today 是否只显示今天的消息, 与$day参数不能同时大于0
-	 * @param $star 是否星标组信息
-	 * @return array[] 同getTopMsg()返回的字段结构相同
-	 */
-	public function getMsg($lastid=0,$offset=0,$perpage=20,$day=7,$today=0,$star=0){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&lang=zh_CN&count=50&token=".$this->_token;
-		$lastid = $lastid===0 ? '':$lastid;
-		$addstar = $star?'&action=star':'';
-		$submit = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&lang=zh_CN{$addstar}&count=$perpage&timeline=$today&day=$day&frommsgid=$lastid&offset=$offset&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$this->log($send_snoopy->results);
-		$result = $send_snoopy->results;
-		$json = json_decode($result,true);
-		if (isset($json['msg_items'])) {
-			$json = json_decode($json['msg_items'],true);
-			if(isset($json['msg_item']))
-				return $json['msg_item'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取图片消息
-	 * @param int $msgid 消息id
-	 * @param string $mode 图片尺寸(large/small)
-	 * @return jpg二进制文件
-	 */
-	public function getMsgImage($msgid,$mode='large'){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/getimgdata?token=".$this->_token."&msgid=$msgid&mode=$mode&source=&fileId=0";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('msg image:'.$msgid.';length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-	
-	/**
-	 * 获取语音消息
-	 * @param int $msgid 消息id
-	 * @return mp3二进制文件
-	 */
-	public function getMsgVoice($msgid){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/getvoicedata?token=".$this->_token."&msgid=$msgid&fileId=0";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('msg voice:'.$msgid.';length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-	
-	/**
-	 * 开启开发者模式
-	 */
-	public function openDevModel()
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN";
-		$post['flag']=1;
-        $post['type']=2;   
-        $post['token']=$this->_token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if(!$result){
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 关闭编辑模式
-	 */
-	public function closeEditModel()
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN";
-		$post['flag']=0;
-        $post['type']=1;   
-        $post['token']=$this->_token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if(!$result){
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 配置接口信息
-	 * @param  string $url      接口回调URL
-	 * @param  string $token    接口Token
-	 */
-	public function setUrlToken($url, $token)
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/interface&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&lang=zh_CN&token=".$this->_token;
-		$post['url'] = $url;
-		$post['callback_token'] = $token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if ($json && $json['ret']==0) 
-			return true;
-		return false;
-	}
-
-	/**
-	 * 快速设置接口
-	 * @param  string $url      接口回调URL
-	 * @param  string $token    接口Token
-	 */
-	public function quickSetInterface($url, $token)
-	{
-		if ($this->closeEditModel() && $this->openDevModel() && $this->setUrlToken($url, $token))
-			return true;
-		return false;
-	}
-	
-	/**
-	 * 模拟登录获取cookie
-	 * @return [type] [description]
-	 */
-	public function login(){
-		$snoopy = new Snoopy; 
-		$submit = "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN";
-		$post["username"] = $this->_account;
-		$post["pwd"] = md5($this->_password);
-		$post["f"] = "json";
-		$post["imgcode"] = "";
-		$snoopy->referer = "https://mp.weixin.qq.com/";
-		$snoopy->submit($submit,$post);
-		$cookie = '';
-		$this->log($snoopy->results);
-		$result = json_decode($snoopy->results,true);
-		
-		if (!isset($result['base_resp']) || $result['base_resp']['ret'] != 0) {
-			return false;
-		}
-        
-		foreach ($snoopy->headers as $key => $value) {
-			$value = trim($value);
-			if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $value,$match))
-				$cookie .=$match[1].'='.$match[2].'; ';
-		}
-		
-		preg_match("/token=(\d+)/i",$result['redirect_url'],$matches);
-		if($matches){
-			$this->_token = $matches[1];
-			$this->log('token:'.$this->_token);
-		}
-		$cookies='{"cookie":"'.$cookie.'","token":"'.$this->_token.'"}';
-		$this->saveCookie($this->_cookiename,$cookies);
-		return $cookie;
-	}
-
-	/**
-	 * 把cookie写入缓存
-	 * @param  string $filename 缓存文件名
-	 * @param  string $content  文件内容
-	 * @return bool
-	 */
-	public function saveCookie($filename,$content){
-		return S($filename,$content,$this->_cookieexpired);
-	}
-
-	/**
-	 * 读取cookie缓存内容
-	 * @param  string $filename 缓存文件名
-	 * @return string cookie
-	 */
-	public function getCookie($filename){
-		$data = S($filename);
-		if($data){
-			$login=json_decode($data,true);
-			$send_snoopy = new Snoopy;
-			$send_snoopy->rawheaders['Cookie']= $login['cookie'];
-			$send_snoopy->maxredirs = 0;
-			$url = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=".$login['token'];
-			$send_snoopy->fetch($url);
-			$header = $send_snoopy->headers;
-			$this->log('header:'.print_r($send_snoopy->headers,true));
-			if( strstr($header[3], 'EXPIRED')){
-				return $this->login();
-			}else{
-				$this->_token =$login['token'];
-				return $login['cookie'];
-			}
-		}else{
-			return $this->login();
-		}
-	}
-
-	/**
-	 * 验证cookie的有效性
-	 * @return bool
-	 */
-	public function checkValid()
-	{
-		if (!$this->cookie || !$this->_token) return false;
-		$send_snoopy = new Snoopy; 
-		$post = array('ajax'=>1,'token'=>$this->_token);
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getregions?id=1017&t=ajax-getregions&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		if(json_decode($result,1)){
-			return true;
-		}else{
-			return false;
-		}
-	}
-
-	private function log($log){
-		if ($this->debug ) {
-			if (function_exists($this->_logcallback)) {
-				if (is_array($log)) $log = print_r($log,true);
-				return call_user_func($this->_logcallback,$log);
-			}elseif (class_exists('Log')) {
-				Log::write('wechat:'.$log, Log::DEBUG);
-			}
-		}
-		return false;
-	}
-}

+ 90 - 56
Thinkphp/qywechat.class.php

@@ -50,6 +50,7 @@ class Wechat
     const USER_LIST_URL = '/user/simplelist?';
     const USER_LIST_INFO_URL = '/user/list?';
     const USER_GETINFO_URL = '/user/getuserinfo?';
+    const USER_INVITE_URL = 'invite/send?';
     const DEPARTMENT_CREATE_URL = '/department/create?';
     const DEPARTMENT_UPDATE_URL = '/department/update?';
     const DEPARTMENT_DELETE_URL = '/department/delete?';
@@ -73,7 +74,7 @@ class Wechat
 	const CALLBACKSERVER_GET_URL = '/getcallbackip?';
 	const OAUTH_PREFIX = 'https://open.weixin.qq.com/connect/oauth2';
 	const OAUTH_AUTHORIZE_URL = '/authorize?';
-	
+
 	private $token;
 	private $encodingAesKey;
 	private $appid;         //也就是企业号的CorpID
@@ -90,7 +91,7 @@ class Wechat
 	public $errCode = 40001;
 	public $errMsg = "no access";
 	private $_logcallback;
-	
+
 	public function __construct($options)
 	{
 		$this->token = isset($options['token'])?$options['token']:'';
@@ -101,7 +102,7 @@ class Wechat
 		$this->debug = isset($options['debug'])?$options['debug']:false;
 		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
 	}
-	
+
 	private function log($log){
 	    if ($this->debug ) {
 	        if (function_exists($this->_logcallback)) {
@@ -130,12 +131,12 @@ class Wechat
 	    }
 	    return $xml;
 	}
-	
+
 	public static function xmlSafeStr($str)
 	{
 	    return '<![CDATA['.preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/",'',$str).']]>';
 	}
-	
+
 	/**
 	 * XML编码
 	 * @param mixed $data 数据
@@ -161,7 +162,7 @@ class Wechat
 	    $xml   .= "</{$root}>";
 	    return $xml;
 	}
-	
+
 
 	/**
 	 * 微信api不支持中文转义的json结构
@@ -210,7 +211,7 @@ class Wechat
 	        return '[' . $json . ']'; //Return numerical JSON
 	    return '{' . $json . '}'; //Return associative JSON
 	}
-	
+
 	/**
 	 * 过滤文字回复\r\n换行符
 	 * @param string $text
@@ -220,7 +221,7 @@ class Wechat
 	    if (!$this->_text_filter) return $text;
 	    return str_replace("\r\n", "\n", $text);
 	}
-	
+
 	/**
 	 * GET 请求
 	 * @param string $url
@@ -243,7 +244,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * POST 请求
 	 * @param string $url
@@ -299,7 +300,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 微信验证,包括post来的xml解密
 	 * @param bool $return 是否返回
@@ -352,7 +353,7 @@ class Wechat
         }
         return false;
     }
-    
+
     /**
      * 获取微信服务器发来的信息
      */
@@ -369,7 +370,7 @@ class Wechat
 		}
 		return $this;
 	}
-	
+
 	/**
 	 * 获取微信服务器发来的信息
 	 */
@@ -377,7 +378,7 @@ class Wechat
 	{
 		return $this->_receive;
 	}
-	
+
 	/**
 	 * 获取微信服务器发来的原始加密信息
 	 */
@@ -385,7 +386,7 @@ class Wechat
 	{
 	    return $this->postxml;
 	}
-	
+
 	/**
 	 * 获取消息发送者
 	 */
@@ -395,7 +396,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息接受者
 	 */
@@ -405,7 +406,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息的应用id
 	 */
@@ -425,7 +426,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息ID
 	 */
@@ -435,7 +436,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息发送时间
 	 */
@@ -445,7 +446,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息内容正文
 	 */
@@ -455,7 +456,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息图片
 	 */
@@ -468,7 +469,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收地理位置
 	 */
@@ -483,7 +484,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取上报地理位置事件
 	 */
@@ -497,7 +498,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收事件推送
 	 */
@@ -543,7 +544,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取自定义菜单的图片发送事件信息
 	 *
@@ -587,7 +588,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取自定义菜单的地理位置选择器事件推送
 	 *
@@ -625,7 +626,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取接收语音推送
 	 */
@@ -638,7 +639,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收视频推送
 	 */
@@ -651,7 +652,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->text('hello')->reply();
@@ -669,7 +670,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->image('media_id')->reply();
@@ -687,7 +688,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->voice('media_id')->reply();
@@ -705,7 +706,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->video('media_id','title','description')->reply();
@@ -727,7 +728,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复图文
 	 * @param array $newsData
@@ -746,7 +747,7 @@ class Wechat
 	{
 
 		$count = count($newsData);
-		
+
 		$msg = array(
 			'ToUserName' => $this->getRevFrom(),
 			'FromUserName'=>$this->getRevTo(),
@@ -759,7 +760,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置发送消息
 	 * @param array $msg 消息数组
@@ -813,7 +814,7 @@ class Wechat
 		elseif ($smsg){
 			echo $smsg;
 		    return true;
-		    
+
 		}else
 		    return false;
 	}
@@ -829,7 +830,7 @@ class Wechat
 </xml>";
 	    return sprintf($format, $encrypt, $signature, $timestamp, $nonce);
 	}
-	
+
 
 	/**
 	 * 通用auth验证方法
@@ -951,7 +952,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 获取菜单
 	 * @return array('menu'=>array(....s))
@@ -974,7 +975,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 删除菜单
 	 * @return boolean
@@ -1026,7 +1027,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 根据媒体文件ID获取媒体文件
 	 * @param string $media_id 媒体文件id
@@ -1047,7 +1048,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 获取企业微信服务器IP地址列表
 	 * @return array('127.0.0.1','127.0.0.1')
@@ -1099,7 +1100,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 
 	/**
 	 * 更新部门
@@ -1186,7 +1187,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门列表
 	 * @return boolean|array	 成功返回结果
@@ -1259,8 +1260,8 @@ class Wechat
 	    }
 	    return false;
 	}
-	
-	
+
+
 	/**
 	 * 更新成员
 	 * @param array $data 	结构体为:
@@ -1296,7 +1297,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除成员
 	 * @param $userid  员工UserID。对应管理端的帐号
@@ -1321,7 +1322,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 批量删除成员
 	 * @param array $userid  员工UserID数组。对应管理端的帐号
@@ -1353,7 +1354,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取成员信息
 	 * @param $userid  员工UserID。对应管理端的帐号
@@ -1390,7 +1391,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门成员
 	 * @param $department_id   部门id
@@ -1424,7 +1425,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门成员详情
 	 * @param $department_id   部门id
@@ -1499,6 +1500,39 @@ class Wechat
 	}
 
 	/**
+	 * 邀请成员关注
+	 * 向未关注企业号的成员发送关注邀请。认证号优先判断顺序weixinid>手机号>邮箱绑定>邮件;非认证号只能邮件邀请
+	 *
+	 * @param $userid        用户的userid
+	 * @param $invite_tips   推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。
+	 * @return boolean|array 成功返回数组
+	 * array(
+	 *     'errcode' => 0,
+	 *     'errmsg' => 'ok',
+	 *     'type' => 1         //邀请方式 1.微信邀请 2.邮件邀请
+	 * )
+	 */
+	public function sendInvite($userid,$invite_tips=''){
+	    $data = array( 'userid' => $userid );
+	    if (!$invite_tips) {
+	    	$data['invite_tips'] = $invite_tips
+	    }
+	    if (!$this->access_token && !$this->checkAuth()) return false;
+	    $result = $this->http_post(self::API_URL_PREFIX.self::USER_INVITE_URL.'access_token='.$this->access_token,self::json_encode($data));
+	    if ($result)
+	    {
+	        $json = json_decode($result,true);
+	        if (!$json || !empty($json['errcode'])) {
+	            $this->errCode = $json['errcode'];
+	            $this->errMsg = $json['errmsg'];
+	            return false;
+	        }
+	        return $json;
+	    }
+	    return false;
+	}
+
+	/**
 	 * 创建标签
 	 * @param array $data 	结构体为:
 	 * array(
@@ -1527,7 +1561,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 更新标签
 	 * @param array $data 	结构体为:
@@ -1556,7 +1590,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除标签
 	 * @param $tagid  标签TagID
@@ -1581,7 +1615,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取标签成员
 	 * @param $tagid  标签TagID
@@ -1612,7 +1646,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 增加标签成员
 	 * @param array $data 	结构体为:
@@ -1646,7 +1680,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除标签成员
 	 * @param array $data 	结构体为:
@@ -1680,7 +1714,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取标签列表
 	 * @return boolean|array	 成功返回数组结果,这里附上json样例
@@ -1826,7 +1860,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * oauth 授权跳转接口
 	 * @param string $callback 回调URI

+ 2 - 1
demo.php

@@ -1,7 +1,8 @@
 <?php
 include "wechat.class.php";
 $options = array(
-		'token'=>'tokenaccesskey' //填写你设定的key
+		'token'=>'tokenaccesskey', //填写你设定的key
+        'encodingaeskey'=>'encodingaeskey' //填写加密用的EncodingAESKey,如接口为明文模式可忽略
 	);
 $weObj = new Wechat($options);
 $weObj->valid();//明文或兼容模式可以在接口验证通过后注释此句,但加密模式一定不能注释,否则会验证失败

Thinkphp/Snoopy.class.php → old_version/Thinkphp/Snoopy.class.php


+ 5 - 14
old_version/Thinkphp/Wechatpay.class.php

@@ -1,6 +1,6 @@
 <?php
 /**
- *	微信公众平台PHP-SDK, 旧版微信支付接口
+ *	微信公众平台PHP-SDK, 旧版微信支付接口(微信支付V2)
  *  @author  dodge <dodgepudding@gmail.com>
  *  @link https://github.com/dodgepudding/wechat-php-sdk
  *  @version 1.2
@@ -122,9 +122,9 @@ class Wechatpay
 	}
 
 	/**
-	 * 通用auth验证方法,暂时仅用于菜单更新操作
-	 * @param string $appid
-	 * @param string $appsecret
+	 * 获取access_token
+	 * @param string $appid 如在类初始化时已提供,则可为空
+	 * @param string $appsecret 如在类初始化时已提供,则可为空
 	 * @param string $token 手动指定access_token,非必要情况不建议用
 	 */
 	public function checkAuth($appid='',$appsecret='',$token=''){
@@ -421,16 +421,7 @@ class Wechatpay
 		}
 		return false;
 	}
-	
-	/**
-	 * 设置用户授权密钥
-	 * @param string $user_token
-	 * @return string
-	 */
-	public function setUserToken($user_token) {
-		return $this->user_token = $user_token;
-	}
-	
+
 	/**
 	 * 设置用户授权密钥
 	 * @param string $user_token

snoopy.class.php → old_version/snoopy.class.php


test/test2.php → old_version/test/test2.php


test/test3.php → old_version/test/test3.php


test/weshare.html → old_version/test/weshare.html


+ 1 - 1
wechat.js

@@ -1,5 +1,5 @@
 /**
- * 微信网页端调用JS
+ * 微信网页端调用JS(官方于微信6.0.2版本发布新版JSAPI接口,此接口文件废弃)
  * @author dodge
  * @contact dodgepudding@gmail.com
  * @link http://blog.4wer.com/wechat-timeline-share

+ 5 - 5
old_version/wechatpay.class.php

@@ -1,6 +1,6 @@
 <?php
 /**
- *	微信公众平台PHP-SDK, 旧版微信支付接口
+ *	微信公众平台PHP-SDK, 旧版微信支付接口(微信支付V2)
  *  @author  dodge <dodgepudding@gmail.com>
  *  @link https://github.com/dodgepudding/wechat-php-sdk
  *  @version 1.2
@@ -117,9 +117,9 @@ class Wechatpay
 	}
 
 	/**
-	 * 通用auth验证方法,暂时仅用于菜单更新操作
-	 * @param string $appid
-	 * @param string $appsecret
+	 * 获取access_token
+	 * @param string $appid 如在类初始化时已提供,则可为空
+	 * @param string $appsecret 如在类初始化时已提供,则可为空
 	 * @param string $token 手动指定access_token,非必要情况不建议用
 	 */
 	public function checkAuth($appid='',$appsecret='',$token=''){
@@ -411,7 +411,7 @@ class Wechatpay
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 设置用户授权密钥
 	 * @param string $user_token

+ 90 - 56
qywechat.class.php

@@ -50,6 +50,7 @@ class Wechat
     const USER_LIST_URL = '/user/simplelist?';
     const USER_LIST_INFO_URL = '/user/list?';
     const USER_GETINFO_URL = '/user/getuserinfo?';
+    const USER_INVITE_URL = 'invite/send?';
     const DEPARTMENT_CREATE_URL = '/department/create?';
     const DEPARTMENT_UPDATE_URL = '/department/update?';
     const DEPARTMENT_DELETE_URL = '/department/delete?';
@@ -73,7 +74,7 @@ class Wechat
 	const CALLBACKSERVER_GET_URL = '/getcallbackip?';
 	const OAUTH_PREFIX = 'https://open.weixin.qq.com/connect/oauth2';
 	const OAUTH_AUTHORIZE_URL = '/authorize?';
-	
+
 	private $token;
 	private $encodingAesKey;
 	private $appid;         //也就是企业号的CorpID
@@ -90,7 +91,7 @@ class Wechat
 	public $errCode = 40001;
 	public $errMsg = "no access";
 	private $_logcallback;
-	
+
 	public function __construct($options)
 	{
 		$this->token = isset($options['token'])?$options['token']:'';
@@ -101,7 +102,7 @@ class Wechat
 		$this->debug = isset($options['debug'])?$options['debug']:false;
 		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
 	}
-	
+
 	private function log($log){
 	    if ($this->debug && function_exists($this->_logcallback)) {
 	        if (is_array($log)) $log = print_r($log,true);
@@ -125,12 +126,12 @@ class Wechat
 	    }
 	    return $xml;
 	}
-	
+
 	public static function xmlSafeStr($str)
 	{
 	    return '<![CDATA['.preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/",'',$str).']]>';
 	}
-	
+
 	/**
 	 * XML编码
 	 * @param mixed $data 数据
@@ -156,7 +157,7 @@ class Wechat
 	    $xml   .= "</{$root}>";
 	    return $xml;
 	}
-	
+
 
 	/**
 	 * 微信api不支持中文转义的json结构
@@ -205,7 +206,7 @@ class Wechat
 	        return '[' . $json . ']'; //Return numerical JSON
 	    return '{' . $json . '}'; //Return associative JSON
 	}
-	
+
 	/**
 	 * 过滤文字回复\r\n换行符
 	 * @param string $text
@@ -215,7 +216,7 @@ class Wechat
 	    if (!$this->_text_filter) return $text;
 	    return str_replace("\r\n", "\n", $text);
 	}
-	
+
 	/**
 	 * GET 请求
 	 * @param string $url
@@ -238,7 +239,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * POST 请求
 	 * @param string $url
@@ -294,7 +295,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 微信验证,包括post来的xml解密
 	 * @param bool $return 是否返回
@@ -347,7 +348,7 @@ class Wechat
         }
         return false;
     }
-    
+
     /**
      * 获取微信服务器发来的信息
      */
@@ -364,7 +365,7 @@ class Wechat
 		}
 		return $this;
 	}
-	
+
 	/**
 	 * 获取微信服务器发来的信息
 	 */
@@ -372,7 +373,7 @@ class Wechat
 	{
 		return $this->_receive;
 	}
-	
+
 	/**
 	 * 获取微信服务器发来的原始加密信息
 	 */
@@ -380,7 +381,7 @@ class Wechat
 	{
 	    return $this->postxml;
 	}
-	
+
 	/**
 	 * 获取消息发送者
 	 */
@@ -390,7 +391,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息接受者
 	 */
@@ -400,7 +401,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息的应用id
 	 */
@@ -420,7 +421,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息ID
 	 */
@@ -430,7 +431,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取消息发送时间
 	 */
@@ -440,7 +441,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息内容正文
 	 */
@@ -450,7 +451,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收消息图片
 	 */
@@ -463,7 +464,7 @@ class Wechat
 		else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收地理位置
 	 */
@@ -478,7 +479,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取上报地理位置事件
 	 */
@@ -492,7 +493,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收事件推送
 	 */
@@ -538,7 +539,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取自定义菜单的图片发送事件信息
 	 *
@@ -582,7 +583,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取自定义菜单的地理位置选择器事件推送
 	 *
@@ -620,7 +621,7 @@ class Wechat
 	        return false;
 	    }
 	}
-	
+
 	/**
 	 * 获取接收语音推送
 	 */
@@ -633,7 +634,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 获取接收视频推送
 	 */
@@ -646,7 +647,7 @@ class Wechat
 		} else
 			return false;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->text('hello')->reply();
@@ -664,7 +665,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->image('media_id')->reply();
@@ -682,7 +683,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->voice('media_id')->reply();
@@ -700,7 +701,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复消息
 	 * Example: $obj->video('media_id','title','description')->reply();
@@ -722,7 +723,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置回复图文
 	 * @param array $newsData
@@ -741,7 +742,7 @@ class Wechat
 	{
 
 		$count = count($newsData);
-		
+
 		$msg = array(
 			'ToUserName' => $this->getRevFrom(),
 			'FromUserName'=>$this->getRevTo(),
@@ -754,7 +755,7 @@ class Wechat
 		$this->Message($msg);
 		return $this;
 	}
-	
+
 	/**
 	 * 设置发送消息
 	 * @param array $msg 消息数组
@@ -808,7 +809,7 @@ class Wechat
 		elseif ($smsg){
 			echo $smsg;
 		    return true;
-		    
+
 		}else
 		    return false;
 	}
@@ -824,7 +825,7 @@ class Wechat
 </xml>";
 	    return sprintf($format, $encrypt, $signature, $timestamp, $nonce);
 	}
-	
+
 
 	/**
 	 * 通用auth验证方法
@@ -942,7 +943,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 获取菜单
 	 * @return array('menu'=>array(....s))
@@ -965,7 +966,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 删除菜单
 	 * @return boolean
@@ -1017,7 +1018,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 根据媒体文件ID获取媒体文件
 	 * @param string $media_id 媒体文件id
@@ -1038,7 +1039,7 @@ class Wechat
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 获取企业微信服务器IP地址列表
 	 * @return array('127.0.0.1','127.0.0.1')
@@ -1090,7 +1091,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 
 	/**
 	 * 更新部门
@@ -1177,7 +1178,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门列表
 	 * @return boolean|array	 成功返回结果
@@ -1250,8 +1251,8 @@ class Wechat
 	    }
 	    return false;
 	}
-	
-	
+
+
 	/**
 	 * 更新成员
 	 * @param array $data 	结构体为:
@@ -1287,7 +1288,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除成员
 	 * @param $userid  员工UserID。对应管理端的帐号
@@ -1312,7 +1313,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 批量删除成员
 	 * @param array $userid  员工UserID数组。对应管理端的帐号
@@ -1344,7 +1345,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取成员信息
 	 * @param $userid  员工UserID。对应管理端的帐号
@@ -1381,7 +1382,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门成员
 	 * @param $department_id   部门id
@@ -1415,7 +1416,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取部门成员详情
 	 * @param $department_id   部门id
@@ -1490,6 +1491,39 @@ class Wechat
 	}
 
 	/**
+	 * 邀请成员关注
+	 * 向未关注企业号的成员发送关注邀请。认证号优先判断顺序weixinid>手机号>邮箱绑定>邮件;非认证号只能邮件邀请
+	 *
+	 * @param $userid        用户的userid
+	 * @param $invite_tips   推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。
+	 * @return boolean|array 成功返回数组
+	 * array(
+	 *     'errcode' => 0,
+	 *     'errmsg' => 'ok',
+	 *     'type' => 1         //邀请方式 1.微信邀请 2.邮件邀请
+	 * )
+	 */
+	public function sendInvite($userid,$invite_tips=''){
+	    $data = array( 'userid' => $userid );
+	    if (!$invite_tips) {
+	    	$data['invite_tips'] = $invite_tips
+	    }
+	    if (!$this->access_token && !$this->checkAuth()) return false;
+	    $result = $this->http_post(self::API_URL_PREFIX.self::USER_INVITE_URL.'access_token='.$this->access_token,self::json_encode($data));
+	    if ($result)
+	    {
+	        $json = json_decode($result,true);
+	        if (!$json || !empty($json['errcode'])) {
+	            $this->errCode = $json['errcode'];
+	            $this->errMsg = $json['errmsg'];
+	            return false;
+	        }
+	        return $json;
+	    }
+	    return false;
+	}
+
+	/**
 	 * 创建标签
 	 * @param array $data 	结构体为:
 	 * array(
@@ -1518,7 +1552,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 更新标签
 	 * @param array $data 	结构体为:
@@ -1547,7 +1581,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除标签
 	 * @param $tagid  标签TagID
@@ -1572,7 +1606,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取标签成员
 	 * @param $tagid  标签TagID
@@ -1603,7 +1637,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 增加标签成员
 	 * @param array $data 	结构体为:
@@ -1637,7 +1671,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 删除标签成员
 	 * @param array $data 	结构体为:
@@ -1671,7 +1705,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * 获取标签列表
 	 * @return boolean|array	 成功返回数组结果,这里附上json样例
@@ -1817,7 +1851,7 @@ class Wechat
 	    }
 	    return false;
 	}
-	
+
 	/**
 	 * oauth 授权跳转接口
 	 * @param string $callback 回调URI

+ 543 - 0
test/jsapi/jsapi-demo-6.1.js

@@ -0,0 +1,543 @@
+wx.ready(function () {
+	alert("启动jsapi!");
+  // 1 判断当前版本是否支持指定 JS 接口,支持批量判断
+  document.querySelector('#checkJsApi').onclick = function () {
+    wx.checkJsApi({
+      jsApiList: [
+                  'checkJsApi',
+                  'onMenuShareTimeline',
+                  'onMenuShareAppMessage',
+                  'onMenuShareQQ',
+                  'onMenuShareWeibo',
+                  'hideMenuItems',
+                  'showMenuItems',
+                  'hideAllNonBaseMenuItem',
+                  'showAllNonBaseMenuItem',
+                  'translateVoice',
+                  'startRecord',
+                  'stopRecord',
+                  'onRecordEnd',
+                  'playVoice',
+                  'pauseVoice',
+                  'stopVoice',
+                  'uploadVoice',
+                  'downloadVoice',
+                  'chooseImage',
+                  'previewImage',
+                  'uploadImage',
+                  'downloadImage',
+                  'getNetworkType',
+                  'openLocation',
+                  'getLocation',
+                  'hideOptionMenu',
+                  'showOptionMenu',
+                  'closeWindow',
+                  'scanQRCode',
+                  'chooseWXPay',
+                  'openProductSpecificView',
+                  'addCard',
+                  'chooseCard',
+                  'openCard'
+                ],
+      success: function (res) {
+      	alert("检测通过:"  +JSON.stringify(res));
+      },
+      fail: function(res) {
+      	alert("检测失败:"  +JSON.stringify(res));
+      },
+      complete: function(res) {
+      	alert("检测结束");
+      }
+    });
+  };
+
+  // 2. 分享接口
+  // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口
+  document.querySelector('#onMenuShareAppMessage').onclick = function () {
+    wx.onMenuShareAppMessage({
+      title: 'wechat-php-sdk博客',
+      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人:dodgepudding 项目地址:https://github.com/dodgepudding/wechat-php-sdk',
+      link: 'http://binsee.github.io/wechat-php-sdk/',
+      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',
+      trigger: function (res) {
+      	alert("点击分享:" +JSON.stringify(res));
+          // 用户确认分享后执行的回调函数
+      },
+      success: function (res) {
+      	alert("分享成功:" +JSON.stringify(res));
+          // 用户确认分享后执行的回调函数
+      },
+      cancel: function (res) {
+      	alert("取消分享:" +JSON.stringify(res));
+          // 用户取消分享后执行的回调函数
+      },
+      fail:function (res) {
+      	alert("分享失败:" +JSON.stringify(res));
+      }
+    });
+    alert('已注册获取“发送给朋友”状态事件');
+  };
+
+  // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
+  document.querySelector('#onMenuShareTimeline').onclick = function () {
+    wx.onMenuShareTimeline({
+      title: 'wechat-php-sdk博客',
+      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人:dodgepudding 项目地址:https://github.com/dodgepudding/wechat-php-sdk',
+      link: 'http://binsee.github.io/wechat-php-sdk/',
+      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',
+      trigger: function (res) {
+        	alert("点击分享:" +JSON.stringify(res));
+            // 用户确认分享后执行的回调函数
+        },
+        success: function (res) {
+        	alert("分享成功:" +JSON.stringify(res));
+            // 用户确认分享后执行的回调函数
+        },
+        cancel: function (res) {
+        	alert("取消分享:" +JSON.stringify(res));
+            // 用户取消分享后执行的回调函数
+        },
+        fail:function (res) {
+        	alert("分享失败:" +JSON.stringify(res));
+        }
+    });
+    alert('已注册获取“分享到朋友圈”状态事件');
+  };
+
+  // 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口
+  document.querySelector('#onMenuShareQQ').onclick = function () {
+    wx.onMenuShareQQ({
+      title: 'wechat-php-sdk博客',
+      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人:dodgepudding 项目地址:https://github.com/dodgepudding/wechat-php-sdk',
+      link: 'http://binsee.github.io/wechat-php-sdk/',
+      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',
+      trigger: function (res) {
+      	alert("点击分享:" +JSON.stringify(res));
+          // 用户确认分享后执行的回调函数
+      },
+      success: function (res) {
+      	alert("分享成功:" +JSON.stringify(res));
+          // 用户确认分享后执行的回调函数
+      },
+      cancel: function (res) {
+      	alert("取消分享:" +JSON.stringify(res));
+          // 用户取消分享后执行的回调函数
+      },
+      fail:function (res) {
+      	alert("分享失败:" +JSON.stringify(res));
+      }
+    });
+    alert('已注册获取“分享到 QQ”状态事件');
+  };
+  
+  // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口
+  document.querySelector('#onMenuShareWeibo').onclick = function () {
+    wx.onMenuShareWeibo({
+      title: 'wechat-php-sdk博客',
+      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人:dodgepudding 项目地址:https://github.com/dodgepudding/wechat-php-sdk',
+      link: 'http://binsee.github.io/wechat-php-sdk/',
+      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',
+      trigger: function (res) {
+        	alert("点击分享:" +JSON.stringify(res));
+            // 用户确认分享后执行的回调函数
+        },
+        success: function (res) {
+        	alert("分享成功:" +JSON.stringify(res));
+            // 用户确认分享后执行的回调函数
+        },
+        cancel: function (res) {
+        	alert("取消分享:" +JSON.stringify(res));
+            // 用户取消分享后执行的回调函数
+        },
+        fail:function (res) {
+        	alert("分享失败:" +JSON.stringify(res));
+        }
+    });
+    alert('已注册获取“分享到微博”状态事件');
+  };
+
+
+  // 3 智能接口
+  var voice = {
+    localId: '',
+    serverId: ''
+  };
+  // 3.1 识别音频并返回识别结果
+  document.querySelector('#translateVoice').onclick = function () {
+    if (voice.localId == '') {
+      alert('请先使用 startRecord 接口录制一段声音');
+      return;
+    }
+    wx.translateVoice({
+      localId: voice.localId,
+      complete: function (res) {
+        if (res.hasOwnProperty('translateResult')) {
+          alert('识别结果:' + res.translateResult);
+        } else {
+          alert('无法识别');
+        }
+      }
+    });
+  };
+
+  // 4 音频接口
+  // 4.2 开始录音
+  document.querySelector('#startRecord').onclick = function () {
+    wx.startRecord({
+      cancel: function () {
+        alert('用户拒绝授权录音');
+      }
+    });
+  };
+
+  // 4.3 停止录音
+  document.querySelector('#stopRecord').onclick = function () {
+    wx.stopRecord({
+      success: function (res) {
+        voice.localId = res.localId;
+      },
+      fail: function (res) {
+        alert(JSON.stringify(res));
+      }
+    });
+  };
+
+  // 4.4 监听录音自动停止
+  wx.onVoiceRecordEnd({
+    complete: function (res) {
+      voice.localId = res.localId;
+      alert('录音时间已超过一分钟');
+    }
+  });
+
+  // 4.5 播放音频
+  document.querySelector('#playVoice').onclick = function () {
+    if (voice.localId == '') {
+      alert('请先使用 startRecord 接口录制一段声音');
+      return;
+    }
+    wx.playVoice({
+      localId: voice.localId
+    });
+  };
+
+  // 4.6 暂停播放音频
+  document.querySelector('#pauseVoice').onclick = function () {
+    wx.pauseVoice({
+      localId: voice.localId
+    });
+  };
+
+  // 4.7 停止播放音频
+  document.querySelector('#stopVoice').onclick = function () {
+    wx.stopVoice({
+      localId: voice.localId
+    });
+  };
+
+  // 4.8 监听录音播放停止
+  wx.onVoicePlayEnd({
+    complete: function (res) {
+      alert('录音(' + res.localId + ')播放结束');
+    }
+  });
+
+  // 4.8 上传语音
+  document.querySelector('#uploadVoice').onclick = function () {
+    if (voice.localId == '') {
+      alert('请先使用 startRecord 接口录制一段声音');
+      return;
+    }
+    wx.uploadVoice({
+      localId: voice.localId,
+      success: function (res) {
+        alert('上传语音成功,serverId 为' + res.serverId);
+        voice.serverId = res.serverId;
+        alert("上传语音信息:" + JSON.stringify(res));
+      }
+    });
+  };
+
+  // 4.9 下载语音
+  document.querySelector('#downloadVoice').onclick = function () {
+    if (voice.serverId == '') {
+      alert('请先使用 uploadVoice 上传声音');
+      return;
+    }
+    wx.downloadVoice({
+      serverId: voice.serverId,
+      success: function (res) {
+        alert('下载语音成功,localId 为' + res.localId);
+        voice.localId = res.localId;
+        alert("下载语音信息:" + JSON.stringify(res));
+      }
+    });
+  };
+
+  // 5 图片接口
+  // 5.1 拍照、本地选图
+  var images = {
+    localId: [],
+    serverId: []
+  };
+  document.querySelector('#chooseImage').onclick = function () {
+    wx.chooseImage({
+      success: function (res) {
+        images.localId = res.localIds;
+        alert('已选择 ' + res.localIds.length + ' 张图片');
+      }
+    });
+  };
+
+  // 5.2 图片预览
+  document.querySelector('#previewImage').onclick = function () {
+    wx.previewImage({
+      current: 'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
+      urls: [
+        'http://img3.douban.com/view/photo/photo/public/p2152117150.jpg',
+        'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',
+        'http://img3.douban.com/view/photo/photo/public/p2152134700.jpg'
+      ]
+    });
+  };
+
+  // 5.3 上传图片
+  document.querySelector('#uploadImage').onclick = function () {
+    if (images.localId.length == 0) {
+      alert('请先使用 chooseImage 接口选择图片');
+      return;
+    }
+    var i = 0, length = images.localId.length;
+    images.serverId = [];
+    function upload() {
+      wx.uploadImage({
+        localId: images.localId[i],
+        success: function (res) {
+          i++;
+            alert('已上传:' + i + '/' + length);
+            alert("上传图片信息:" + JSON.stringify(res));
+          images.serverId.push(res.serverId);
+          if (i < length) {
+            upload();
+          }
+        },
+        fail: function (res) {
+          alert(JSON.stringify(res));
+        }
+      });
+    }
+    upload();
+  };
+
+  // 5.4 下载图片
+  document.querySelector('#downloadImage').onclick = function () {
+    if (images.serverId.length === 0) {
+      alert('请先使用 uploadImage 上传图片');
+      return;
+    }
+    var i = 0, length = images.serverId.length;
+    images.localId = [];
+    function download() {
+      wx.downloadImage({
+        serverId: images.serverId[i],
+        success: function (res) {
+          i++;
+            alert('已下载:' + i + '/' + length);
+            alert("下载图片信息:" + JSON.stringify(res));
+          images.localId.push(res.localId);
+          if (i < length) {
+            download();
+          }
+        }
+      });
+    }
+    download();
+  };
+
+  // 6 设备信息接口
+  // 6.1 获取当前网络状态
+  document.querySelector('#getNetworkType').onclick = function () {
+    wx.getNetworkType({
+      success: function (res) {
+        alert(res.networkType);
+      },
+      fail: function (res) {
+        alert(JSON.stringify(res));
+      }
+    });
+  };
+
+  // 7 地理位置接口
+  // 7.1 查看地理位置
+  document.querySelector('#openLocation').onclick = function () {
+    wx.openLocation({
+      latitude: 23.099994,
+      longitude: 113.324520,
+      name: 'TIT 创意园',
+      address: '广州市海珠区新港中路 397 号',
+      scale: 14,
+      infoUrl: 'http://weixin.qq.com'
+    });
+  };
+
+  // 7.2 获取当前地理位置
+  document.querySelector('#getLocation').onclick = function () {
+    wx.getLocation({
+      success: function (res) {
+        alert(JSON.stringify(res));
+      },
+      cancel: function (res) {
+        alert('用户拒绝授权获取地理位置');
+      }
+    });
+  };
+  
+  // 8 界面操作接口
+  // 8.1 隐藏右上角菜单
+  document.querySelector('#hideOptionMenu').onclick = function () {
+    wx.hideOptionMenu();
+  };
+
+  // 8.2 显示右上角菜单
+  document.querySelector('#showOptionMenu').onclick = function () {
+    wx.showOptionMenu();
+  };
+
+  // 8.3 批量隐藏菜单项
+  document.querySelector('#hideMenuItems').onclick = function () {
+    wx.hideMenuItems({
+      menuList: [
+        'menuItem:readMode', // 阅读模式
+        'menuItem:share:timeline', // 分享到朋友圈
+        'menuItem:copyUrl' // 复制链接
+      ],
+      success: function (res) {
+        alert('已隐藏“阅读模式”,“分享到朋友圈”,“复制链接”等按钮');
+      },
+      fail: function (res) {
+        alert(JSON.stringify(res));
+      }
+    });
+  };
+
+  // 8.4 批量显示菜单项
+  document.querySelector('#showMenuItems').onclick = function () {
+    wx.showMenuItems({
+      menuList: [
+        'menuItem:readMode', // 阅读模式
+        'menuItem:share:timeline', // 分享到朋友圈
+        'menuItem:copyUrl' // 复制链接
+      ],
+      success: function (res) {
+        alert('已显示“阅读模式”,“分享到朋友圈”,“复制链接”等按钮');
+      },
+      fail: function (res) {
+        alert(JSON.stringify(res));
+      }
+    });
+  };
+
+  // 8.5 隐藏所有非基本菜单项
+  document.querySelector('#hideAllNonBaseMenuItem').onclick = function () {
+    wx.hideAllNonBaseMenuItem({
+      success: function () {
+        alert('已隐藏所有非基本菜单项');
+      }
+    });
+  };
+
+  // 8.6 显示所有被隐藏的非基本菜单项
+  document.querySelector('#showAllNonBaseMenuItem').onclick = function () {
+    wx.showAllNonBaseMenuItem({
+      success: function () {
+        alert('已显示所有非基本菜单项');
+      }
+    });
+  };
+
+  // 8.7 关闭当前窗口
+  document.querySelector('#closeWindow').onclick = function () {
+    wx.closeWindow();
+  };
+
+  // 9 微信原生接口
+  // 9.1.1 扫描二维码并返回结果
+  document.querySelector('#scanQRCode0').onclick = function () {
+    wx.scanQRCode({
+      desc: 'scanQRCode desc'
+    });
+  };
+  // 9.1.2 扫描二维码并返回结果
+  document.querySelector('#scanQRCode1').onclick = function () {
+    wx.scanQRCode({
+      needResult: 1,
+      desc: 'scanQRCode desc',
+      success: function (res) {
+        alert(JSON.stringify(res));
+      }
+    });
+  };
+
+  // 10 微信支付接口
+  // 10.1 发起一个支付请求
+  document.querySelector('#chooseWXPay').onclick = function () {
+    wx.chooseWXPay({
+      timestamp: 1414723227,
+      nonceStr: 'noncestr',
+      package: 'addition=action_id%3dgaby1234%26limit_pay%3d&bank_type=WX&body=innertest&fee_type=1&input_charset=GBK&notify_url=http%3A%2F%2F120.204.206.246%2Fcgi-bin%2Fmmsupport-bin%2Fnotifypay&out_trade_no=1414723227818375338&partner=1900000109&spbill_create_ip=127.0.0.1&total_fee=1&sign=432B647FE95C7BF73BCD177CEECBEF8D',
+      paySign: 'bd5b1933cda6e9548862944836a9b52e8c9a2b69'
+    });
+  };
+
+  // 11.3  跳转微信商品页
+  document.querySelector('#openProductSpecificView').onclick = function () {
+    wx.openProductSpecificView({
+      productId: 'pDF3iY0ptap-mIIPYnsM5n8VtCR0'
+    });
+  };
+
+  // 12 微信卡券接口
+  // 12.1 添加卡券
+  document.querySelector('#addCard').onclick = function () {
+    wx.addCard({
+      cardList: [
+        {
+          cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',
+          cardExt: '{"code": "", "openid": "", "timestamp": "1418301401", "signature":"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750"}'
+        },
+        {
+          cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',
+          cardExt: '{"code": "", "openid": "", "timestamp": "1418301401", "signature":"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750"}'
+        }
+      ],
+      success: function (res) {
+        alert('已添加卡券:' + JSON.stringify(res.cardList));
+      }
+    });
+  };
+
+  // 12.2 选择卡券
+  document.querySelector('#chooseCard').onclick = function () {
+    wx.chooseCard({
+      cardSign: '97e9c5e58aab3bdf6fd6150e599d7e5806e5cb91',
+      timestamp: 1417504553,
+      nonceStr: 'k0hGdSXKZEj3Min5',
+      success: function (res) {
+        alert('已选择卡券:' + JSON.stringify(res.cardList));
+      }
+    });
+  };
+
+  // 12.3 查看卡券
+  document.querySelector('#openCard').onclick = function () {
+    alert('您没有该公众号的卡券无法打开卡券。');
+    wx.openCard({
+      cardList: [
+      ]
+    });
+  };
+});
+
+wx.error(function (res) {
+  alert(res.errMsg);
+});

+ 192 - 0
test/jsapi/jsapi_demo.php

@@ -0,0 +1,192 @@
+<?php
+include "wechat.class.php";
+include 'errCode.php';
+
+$opt = array(
+        'appsecret'=>'xxxxxxxxxxxxxxxxxxxxxxxxxx',//填写高级调用功能的密钥
+        'appid'=>'wxxxxxxxxxxxxxx'	//填写高级调用功能的appid
+);
+
+logg("GET参数为:\n".var_export($_GET,true));
+$we = new Wechat($opt);
+$auth = $we->checkAuth();
+$js_ticket = $we->getJsTicket();
+if (!$js_ticket) {
+	echo "获取js_ticket失败!<br>";
+    echo '错误码:'.$we->errCode;
+    echo ' 错误原因:'.ErrCode::getErrText($weObj->errCode);
+    exit;
+}
+$timestamp = time();
+$noncestr = $we->generateNonceStr();
+$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
+$js_sign = $we->getJsSign($url, $timestamp, $noncestr);
+?>
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>JS-SDK测试页</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
+  <link rel="stylesheet" href="style.css?ts=1420775603">
+</head>
+<body ontouchstart="">
+<div class="wxapi_container">
+    <div class="wxapi_index_container">
+      <ul class="label_box lbox_close wxapi_index_list">
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-basic">基础接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-share">分享接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-image">图像接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-voice">音频接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-smart">智能接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-device">设备信息接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-location">地理位置接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-webview">界面操作接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-scan">微信扫一扫接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-shopping">微信小店接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-card">微信卡券接口</a></li>
+        <li class="label_item wxapi_index_item"><a class="label_inner" href="#menu-pay">微信支付接口</a></li>
+      </ul>
+    </div>
+    <div class="lbox_close wxapi_form">
+      <h3 id="menu-basic">基础接口</h3>
+      <span class="desc">判断当前客户端是否支持指定JS接口</span>
+      <button class="btn btn_primary" id="checkJsApi">checkJsApi</button>
+
+      <h3 id="menu-share">分享接口</h3>
+      <span class="desc">获取“分享到朋友圈”按钮点击状态及自定义分享内容接口</span>
+      <button class="btn btn_primary" id="onMenuShareTimeline">onMenuShareTimeline</button>
+      <span class="desc">获取“分享给朋友”按钮点击状态及自定义分享内容接口</span>
+      <button class="btn btn_primary" id="onMenuShareAppMessage">onMenuShareAppMessage</button>
+      <span class="desc">获取“分享到QQ”按钮点击状态及自定义分享内容接口</span>
+      <button class="btn btn_primary" id="onMenuShareQQ">onMenuShareQQ</button>
+      <span class="desc">获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口</span>
+      <button class="btn btn_primary" id="onMenuShareWeibo">onMenuShareWeibo</button>
+
+      <h3 id="menu-image">图像接口</h3>
+      <span class="desc">拍照或从手机相册中选图接口</span>
+      <button class="btn btn_primary" id="chooseImage">chooseImage</button>
+      <span class="desc">预览图片接口</span>
+      <button class="btn btn_primary" id="previewImage">previewImage</button>
+      <span class="desc">上传图片接口</span>
+      <button class="btn btn_primary" id="uploadImage">uploadImage</button>
+      <span class="desc">下载图片接口</span>
+      <button class="btn btn_primary" id="downloadImage">downloadImage</button>
+
+      <h3 id="menu-voice">音频接口</h3>
+      <span class="desc">开始录音接口</span>
+      <button class="btn btn_primary" id="startRecord">startRecord</button>
+      <span class="desc">停止录音接口</span>
+      <button class="btn btn_primary" id="stopRecord">stopRecord</button>
+      <span class="desc">播放语音接口</span>
+      <button class="btn btn_primary" id="playVoice">playVoice</button>
+      <span class="desc">暂停播放接口</span>
+      <button class="btn btn_primary" id="pauseVoice">pauseVoice</button>
+      <span class="desc">停止播放接口</span>
+      <button class="btn btn_primary" id="stopVoice">stopVoice</button>
+      <span class="desc">上传语音接口</span>
+      <button class="btn btn_primary" id="uploadVoice">uploadVoice</button>
+      <span class="desc">下载语音接口</span>
+      <button class="btn btn_primary" id="downloadVoice">downloadVoice</button>
+
+      <h3 id="menu-smart">智能接口</h3>
+      <span class="desc">识别音频并返回识别结果接口</span>
+      <button class="btn btn_primary" id="translateVoice">translateVoice</button>
+
+      <h3 id="menu-device">设备信息接口</h3>
+      <span class="desc">获取网络状态接口</span>
+      <button class="btn btn_primary" id="getNetworkType">getNetworkType</button>
+
+      <h3 id="menu-location">地理位置接口</h3>
+      <span class="desc">使用微信内置地图查看位置接口</span>
+      <button class="btn btn_primary" id="openLocation">openLocation</button>
+      <span class="desc">获取地理位置接口</span>
+      <button class="btn btn_primary" id="getLocation">getLocation</button>
+
+      <h3 id="menu-webview">界面操作接口</h3>
+      <span class="desc">隐藏右上角菜单接口</span>
+      <button class="btn btn_primary" id="hideOptionMenu">hideOptionMenu</button>
+      <span class="desc">显示右上角菜单接口</span>
+      <button class="btn btn_primary" id="showOptionMenu">showOptionMenu</button>
+      <span class="desc">关闭当前网页窗口接口</span>
+      <button class="btn btn_primary" id="closeWindow">closeWindow</button>
+      <span class="desc">批量隐藏功能按钮接口</span>
+      <button class="btn btn_primary" id="hideMenuItems">hideMenuItems</button>
+      <span class="desc">批量显示功能按钮接口</span>
+      <button class="btn btn_primary" id="showMenuItems">showMenuItems</button>
+      <span class="desc">隐藏所有非基础按钮接口</span>
+      <button class="btn btn_primary" id="hideAllNonBaseMenuItem">hideAllNonBaseMenuItem</button>
+      <span class="desc">显示所有功能按钮接口</span>
+      <button class="btn btn_primary" id="showAllNonBaseMenuItem">showAllNonBaseMenuItem</button>
+
+      <h3 id="menu-scan">微信扫一扫</h3>
+      <span class="desc">调起微信扫一扫接口</span>
+      <button class="btn btn_primary" id="scanQRCode0">scanQRCode(微信处理结果)</button>
+      <button class="btn btn_primary" id="scanQRCode1">scanQRCode(直接返回结果)</button>
+
+      <h3 id="menu-shopping">微信小店接口</h3>
+      <span class="desc">跳转微信商品页接口</span>
+      <button class="btn btn_primary" id="openProductSpecificView">openProductSpecificView</button>
+
+      <h3 id="menu-card">微信卡券接口</h3>
+      <span class="desc">批量添加卡券接口</span>
+      <button class="btn btn_primary" id="addCard">addCard</button>
+      <span class="desc">调起适用于门店的卡券列表并获取用户选择列表</span>
+      <button class="btn btn_primary" id="chooseCard">chooseCard</button>
+      <span class="desc">查看微信卡包中的卡券接口</span>
+      <button class="btn btn_primary" id="openCard">openCard</button>
+
+      <h3 id="menu-pay">微信支付接口</h3>
+      <span class="desc">发起一个微信支付请求</span>
+      <button class="btn btn_primary" id="chooseWXPay">chooseWXPay</button>
+    </div>
+  </div>
+</body>
+<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"> </script>
+<script>
+  wx.config({
+      debug: false,
+      appId: '<?php echo $opt['appid']; ?>', // 必填,公众号的唯一标识
+      timestamp: <?php echo $timestamp; ?>, // 必填,生成签名的时间戳
+      nonceStr: '<?php echo $noncestr; ?>', // 必填,生成签名的随机串
+      signature: '<?php echo $js_sign; ?>', // 必填,签名,见附录1
+      jsApiList: [
+        'checkJsApi',
+        'onMenuShareTimeline',
+        'onMenuShareAppMessage',
+        'onMenuShareQQ',
+        'onMenuShareWeibo',
+        'hideMenuItems',
+        'showMenuItems',
+        'hideAllNonBaseMenuItem',
+        'showAllNonBaseMenuItem',
+        'translateVoice',
+        'startRecord',
+        'stopRecord',
+        'onRecordEnd',
+        'playVoice',
+        'pauseVoice',
+        'stopVoice',
+        'uploadVoice',
+        'downloadVoice',
+        'chooseImage',
+        'previewImage',
+        'uploadImage',
+        'downloadImage',
+        'getNetworkType',
+        'openLocation',
+        'getLocation',
+        'hideOptionMenu',
+        'showOptionMenu',
+        'closeWindow',
+        'scanQRCode',
+        'chooseWXPay',
+        'openProductSpecificView',
+        'addCard',
+        'chooseCard',
+        'openCard'
+      ]
+  });
+</script>
+<script src="jsapi-demo-6.1.js?ts=<?php echo $timestamp; ?>"> </script>
+</html>

+ 189 - 0
test/jsapi/style.css

@@ -0,0 +1,189 @@
+html {
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+  -webkit-user-select: none;
+  user-select: none;
+}
+body {
+  line-height: 1.6;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  background-color: #f1f0f6;
+}
+* {
+  margin: 0;
+  padding: 0;
+}
+button {
+  font-family: inherit;
+  font-size: 100%;
+  margin: 0;
+  *font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+ul,
+ol {
+  padding-left: 0;
+  list-style-type: none;
+}
+a {
+  text-decoration: none;
+}
+.label_box {
+  background-color: #ffffff;
+}
+.label_item {
+  padding-left: 15px;
+}
+.label_inner {
+  padding-top: 10px;
+  padding-bottom: 10px;
+  min-height: 24px;
+  position: relative;
+}
+.label_inner:before {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200%;
+  height: 1px;
+  border-top: 1px solid #ededed;
+  -webkit-transform-origin: 0 0;
+  transform-origin: 0 0;
+  -webkit-transform: scale(0.5);
+  transform: scale(0.5);
+  top: auto;
+  bottom: -2px;
+}
+.lbox_close {
+  position: relative;
+}
+.lbox_close:before {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200%;
+  height: 1px;
+  border-top: 1px solid #ededed;
+  -webkit-transform-origin: 0 0;
+  transform-origin: 0 0;
+  -webkit-transform: scale(0.5);
+  transform: scale(0.5);
+}
+.lbox_close:after {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200%;
+  height: 1px;
+  border-top: 1px solid #ededed;
+  -webkit-transform-origin: 0 0;
+  transform-origin: 0 0;
+  -webkit-transform: scale(0.5);
+  transform: scale(0.5);
+  top: auto;
+  bottom: -2px;
+}
+.lbox_close .label_item:last-child .label_inner:before {
+  display: none;
+}
+.btn {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  padding-left: 14px;
+  padding-right: 14px;
+  font-size: 18px;
+  text-align: center;
+  text-decoration: none;
+  overflow: visible;
+  /*.btn_h(@btnHeight);*/
+  height: 42px;
+  border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-border-radius: 5px;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  color: #ffffff;
+  line-height: 42px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.btn.btn_inline {
+  display: inline-block;
+}
+.btn_primary {
+  background-color: #04be02;
+}
+.btn_primary:not(.btn_disabled):visited {
+  color: #ffffff;
+}
+.btn_primary:not(.btn_disabled):active {
+  color: rgba(255, 255, 255, 0.9);
+  background-color: #039702;
+}
+button.btn {
+  width: 100%;
+  border: 0;
+  outline: 0;
+  -webkit-appearance: none;
+}
+button.btn:focus {
+  outline: 0;
+}
+.wxapi_container {
+  font-size: 16px;
+}
+h1 {
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 2em;
+  padding-left: 15px;
+  color: #8d8c92;
+}
+.desc {
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 2em;
+  color: #8d8c92;
+}
+.wxapi_index_item a {
+  display: block;
+  color: #3e3e3e;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.wxapi_form {
+  background-color: #ffffff;
+  padding: 0 15px;
+  margin-top: 30px;
+  padding-bottom: 15px;
+}
+h3 {
+  padding-top: 16px;
+  margin-top: 25px;
+  font-size: 16px;
+  font-weight: 400;
+  color: #3e3e3e;
+  position: relative;
+}
+h3:first-child {
+  padding-top: 15px;
+}
+h3:before {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200%;
+  height: 1px;
+  border-top: 1px solid #ededed;
+  -webkit-transform-origin: 0 0;
+  transform-origin: 0 0;
+  -webkit-transform: scale(0.5);
+  transform: scale(0.5);
+}
+.btn {
+  margin-bottom: 15px;
+}
+

+ 22 - 7
wechat.class.php

@@ -1070,9 +1070,9 @@ class Wechat
 	}
 
 	/**
-	 * 通用auth验证方法,获取access_token
-	 * @param string $appid
-	 * @param string $appsecret
+	 * 获取access_token
+	 * @param string $appid 如在类初始化时已提供,则可为空
+	 * @param string $appsecret 如在类初始化时已提供,则可为空
 	 * @param string $token 手动指定access_token,非必要情况不建议用
 	 */
 	public function checkAuth($appid='',$appsecret='',$token=''){
@@ -1239,10 +1239,26 @@ class Wechat
 			else
 				$paramstring .= "&" . $key . "=" . $value;
 		}
-		$paySign = $method($paramstring);
-		return $paySign;
+		$Sign = $method($paramstring);
+		return $Sign;
 	}
-	
+
+	/**
+	 * 生成随机字串
+	 * @param number $length 长度,默认为16,最长为32字节
+	 * @return string
+	 */
+	public function generateNonceStr($length=16){
+		// 密码字符集,可任意添加你需要的字符
+		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+		$str = "";
+		for($i = 0; $i < $length; $i++)
+		{
+			$str .= $chars[mt_rand(0, strlen($chars) - 1)];
+		}
+		return $str;
+	}
+
 	/**
 	 * 获取微信服务器IP地址列表
 	 * @return array('127.0.0.1','127.0.0.1')
@@ -2053,7 +2069,6 @@ class Wechat
 		}
 	 * @return boolean|array
 	 */
-	
 	public function sendTemplateMessage($data){
 		if (!$this->access_token && !$this->checkAuth()) return false;
 		$result = $this->http_post(self::API_URL_PREFIX.self::TEMPLATE_SEND_URL.'access_token='.$this->access_token,self::json_encode($data));

+ 0 - 271
wechatauth.class.php

@@ -1,271 +0,0 @@
-<?php
-/**
- *	微信公众平台PHP-SDK
- *  Wechatauth为非官方微信登陆API
- *  用户通过扫描网页提供的二维码实现登陆信息获取
- *  主要实现如下功能:
- *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
- *  get_code_image($code='') 将上面获取的授权码转换为图片二维码
- *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
- *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息
- *  get_avatar($url) 获取用户头像图片数据
- *  @author dodge <dodgepudding@gmail.com>
- *  @link https://github.com/dodgepudding/wechat-php-sdk
- *  @version 1.1
- *  
- */
-include "snoopy.class.php";
-class Wechatauth
-{
-	private $cookie;
-	private $skey;
-	private $_cookiename;
-	private $_cookieexpired = 3600;
-	private $_account = 'test';
-	private $_datapath = './data/cookie_';
-	private $debug;
-	private $_logcallback;
-	public $login_user; //当前登陆用户, 调用get_login_info后获取
-	
-	public function __construct($options)
-	{
-		$this->_account = isset($options['account'])?$options['account']:'';
-		$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
-		$this->debug = isset($options['debug'])?$options['debug']:false;
-		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
-		$this->_cookiename = $this->_datapath.$this->_account;
-		$this->getCookie($this->_cookiename);
-	}
-	/**
-	 * 把cookie写入缓存
-	 * @param  string $filename 缓存文件名
-	 * @param  string $content  文件内容
-	 * @return bool
-	 */
-	public function saveCookie($filename,$content){
-		return file_put_contents($filename,$content);
-	}
-
-	/**
-	 * 读取cookie缓存内容
-	 * @param  string $filename 缓存文件名
-	 * @return string cookie
-	 */
-	public function getCookie($filename){
-		if (file_exists($filename)) {
-			$mtime = filemtime($filename);
-			if ($mtime<time()-$this->_cookieexpired) return false;
-			$data = file_get_contents($filename);
-			if ($data) $this->cookie = $data;
-		} 
-		return $this->cookie;
-	}
-	
-	/*
-	 * 删除cookie
-	 */
-	public function deleteCookie($filename) {
-		$this->cookie = '';
-		@unlink($filename);
-		return true;
-	}
-	
-	private function log($log){
-		if ($this->debug && function_exists($this->_logcallback)) {
-			if (is_array($log)) $log = print_r($log,true);
-			return call_user_func($this->_logcallback,$log);
-		}
-	}
-	
-	/**
-	 * 获取登陆二维码对应的授权码
-	 */
-	public function get_login_code(){
-		if ($this->_logincode) return $this->_logincode;
-		$t = time().strval(mt_rand(100,999));
-		$codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->fetch($codeurl);
-		$result = $send_snoopy->results;
-		if ($result) {
-			preg_match("/window.QRLogin.uuid\s+=\s+\"([^\"]+)\"/",$result,$matches);
-			if(count($matches)>1) {
-				$this->_logincode = $matches[1];
-				$_SESSION['login_step'] = 0;
-				return $this->_logincode;
-			}
-		}
-		return $result;
-	}
-
-	/**
-	 * 通过授权码获取对应的二维码图片地址
-	 * @param string $code
-	 * @return string image url
-	 */
-	public function get_code_image($code=''){
-		if ($code=='') $code = $this->_logincode;
-		if (!$code) return false;
-		return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
-	}
-	
-	/**
-	 * 设置二维码对应的授权码
-	 * @param string $code
-	 * @return class $this
-	 */
-	public  function set_login_code($code) {
-		$this->_logincode = $code;
-		return $this;
-	}
-	
-	/**
-	 * 二维码登陆验证
-	 *
-	 * @return status:
-	 * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
-	 * 201: just scaned but not confirm
-	 * 200: confirm then you can get user info
-	 */
-	public function verify_code() {
-		if (!$this->_logincode) return false;
-		$t = time().strval(mt_rand(100,999));
-
-			$url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=0&_='.$t;
-			$send_snoopy = new Snoopy; 
-			$send_snoopy->referer = "https://wx.qq.com/";
-			$send_snoopy->fetch($url);
-			$result = $send_snoopy->results;
-			$this->log('step1:'.$result);
-			if ($result) {
-				preg_match("/window\.code=(\d+)/",$result,$matches);
-				if(count($matches)>1) {
-					$status = intval($matches[1]);
-					if ($status==201) $_SESSION['login_step'] = 1;
-					if ($status==200) {
-						preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
-						preg_match("/window.redirect_uri=\"([^\"]+)\"/",$result,$matcheurl);
-						$this->log('step2:'.print_r($matches,true));
-						if (count($matcheurl)>1) {
-							$ticket = $matches[1];
-							$scan = $matches[2];
-							//$loginurl = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
-							$loginurl = str_replace("wx.qq.com", "wx2.qq.com", $matcheurl[1]).'&fun=old';
-							$urlpart = parse_url($loginurl);
-							$send_snoopy = new Snoopy; 
-							$send_snoopy->referer = "https://{$urlpart['host']}/cgi-bin/mmwebwx-bin/webwxindex?t=chat";
-							$send_snoopy->fetch($loginurl);
-							$result = $send_snoopy->results;
-							$xml = simplexml_load_string($result);
-							if ($xml->ret=="0") $this->skey = $xml->skey;
-							foreach ($send_snoopy->headers as $key => $value) {
-								$value = trim($value);
-								if(strpos($value,'Set-Cookie: ') !== false){
-									$tmp = str_replace("Set-Cookie: ","",$value);
-									$tmparray = explode(';', $tmp);
-									$item = trim($tmparray[0]);
-									$cookie.=$item.';';
-								}
-							}
-							$cookie .="Domain=.qq.com;";
-							$this->cookie = $cookie;
-							$this->log('step3:'.$loginurl.';cookie:'.$cookie.';respond:'.$result);
-							
-							$this->saveCookie($this->_cookiename,$this->cookie);
-						}
-					}
-					return $status;
-				}
-			}
-		return false;
-	}
-	
-	/**
-	 * 获取登陆的cookie
-	 *
-	 * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
-	 * @return string|array
-	 */
-	public function get_login_cookie($is_array = false){
-		if (!$is_array)	return $this->cookie;
-		$c_arr = explode(';',$this->cookie);
-		$cookie = array();
-		foreach($c_arr as $item) {
-			$kitem = explode('=',trim($item));
-			if (count($kitem)>1) {
-				$key = trim($kitem[0]);
-				$val = trim($kitem[1]);
-				if (!empty($val)) $cookie[$key] = $val;
-			}
-		}
-		return $cookie;
-	}
-	
-	/**
-	 * 	 授权登陆后获取用户登陆信息
-	 */
-	public function get_login_info(){
-		if (!$this->cookie) return false;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy = new Snoopy; 
-		$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t.'&skey='.urlencode($this->skey);
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$citems = $this->get_login_cookie(true);
-		$post = array(
-			"BaseRequest"=>array(
-				array(
-					"Uin"=>$citems['wxuin'],
-					"Sid"=>$citems['wxsid'],
-					"Skey"=>$this->skey,
-					"DeviceID"=>''
-				)
-			)
-		);
-		$send_snoopy->submit($submit,json_encode($post));
-		$this->log('login_info:'.$send_snoopy->results);
-		$result = json_decode($send_snoopy->results,true);
-		if ($result['BaseResponse']['Ret']<0) return false;
-		$this->_login_user = $result['User'];
-		return $result;
-	}
-	
-	/**
-	 *  获取头像
-	 *  @param string $url 传入从用户信息接口获取到的头像地址
-	 */
-	public function get_avatar($url) {
-		if (!$this->cookie) return false;
-		if (strpos($url, 'http')===false) {
-			$url = 'http://wx2.qq.com'.$url;
-		}
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		if ($result) 
-			return $result;
-		else
-			return false;
-	}
-	
-	/**
-	 * 登出当前登陆用户
-	 */
-	public function logout(){
-		if (!$this->cookie) return false;
-		preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
-		if (count($matches)>1) $uid = $matches[1];
-		preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
-		if (count($matches)>1) $sid = $matches[1];
-		$this->log('logout: uid='.$uid.';sid='.$sid);
-		$send_snoopy = new Snoopy; 
-		$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://wx2.qq.com/";
-		$send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
-		$this->deleteCookie($this->_cookiename);
-		return true;
-	}
-}

+ 0 - 923
wechatext.class.php

@@ -1,923 +0,0 @@
-<?php
-/**
- *	微信公众平台PHP-SDK
- *  Wechatext为非官方微信发送API
- *  注: 用户id为通过getMsg()方法获取的FakeId值
- *  主要实现如下功能:
- *  send($id,$content) 向某用户id发送微信文字信息
- *  getUserList($page,$pagesize,$groupid) 获取用户信息
- *  getGroupList($page,$pagesize) 获取群组信息
- *  sendNews($id,$msgid) 发送图文消息
- *  getNewsList($page,$pagesize) 获取图文信息列表
- *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频
- *  addPreview($title,$author,$summary,$content,$photoid,$srcurl='')   创建新的图文信息 
- *  getFileList($type,$page,$pagesize) 获取素材库文件列表
- *  sendImage($id,$fid) 发送图片消息
- *  sendAudio($id,$fid) 发送音频消息
- *  sendVideo($id,$fid) 发送视频消息
- *  getInfo($id) 根据id获取用户资料
- *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目
- *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据
- *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数
- *  消息返回结构:  {"id":"消息id","type":"类型号(1为文字,2为图片,3为语音)","fileId":"0","hasReply":"0","fakeId":"用户uid","nickName":"昵称","dateTime":"时间戳","content":"文字内容"} 
- *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据
- *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据
- *  quickSetInterface($url, $token) 快速设置接口信息
- *  getCommonInfo($dir) 获取公众账号基本信息, 其中包含:nickname,avatar,type,qrcode,appid,appsecret
- *  @author dodge <dodgepudding@gmail.com>
- *  @link https://github.com/dodgepudding/wechat-php-sdk
- *  @version 1.2
- *  
- */
-
-include "snoopy.class.php";
-class Wechatext
-{
-	private $cookie;
-	private $_cookiename;
-	private $_cookieexpired = 3600;
-	private $_account;
-	private $_password;
-	private $_datapath = './data/cookie_';
-	private $debug;
-	private $_logcallback;
-	private $_token;
-	
-	public function __construct($options)
-	{
-		$this->_account = isset($options['account'])?$options['account']:'';
-		$this->_password = isset($options['password'])?$options['password']:'';
-		$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
-		$this->debug = isset($options['debug'])?$options['debug']:false;
-		$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
-		$this->_cookiename = $this->_datapath.$this->_account;
-		$this->cookie = $this->getCookie($this->_cookiename);
-	}
-
-	/**
-	 * 主动发消息
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $content 发送的内容
-	 */
-	public function send($id,$content)
-	{
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = 1;
-		$post['token'] = $this->_token;
-		$post['content'] = $content;
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$id&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 群发功能 纯文本
-	 * @param string $content
-	 * @return string
-	 */
-	public function mass($content) {
-		$send_snoopy = new Snoopy;
-		$post = array();
-		$post['type'] = 1;
-		$post['token'] = $this->_token;
-		$post['content'] = $content;
-		$post['ajax'] = 1;
-		$post['city']='';
-		$post['country']='';
-		$post['f']='json';
-		$post['groupid']='-1';
-		$post['imgcode']='';
-		$post['lang']='zh_CN';
-		$post['province']='';
-		$post['random']=  rand(0, 1);
-		$post['sex']=0;
-		$post['synctxnews']=0;
-		$post['synctxweibo']=0;
-		$post['t']='ajax-response';
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/masssend";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 群发功能 图文素材
-	 * @param int $appmsgid 图文素材ID
-	 * @return string
-	 */
-	function massNews($appmsgid){
-		$send_snoopy = new Snoopy;
-		$post = array();
-		$post['type'] = 10;
-		$post['token'] = $this->_token;
-		$post['appmsgid'] = $appmsgid;
-		$post['ajax'] = 1;
-		$post['city']='';
-		$post['country']='';
-		$post['f']='json';
-		$post['groupid']='-1';
-		$post['imgcode']='';
-		$post['lang']='zh_CN';
-		$post['province']='';
-		$post['random']=  rand(0, 1);
-		$post['sex']=0;
-		$post['synctxnews']=0;
-		$post['synctxweibo']=0;
-		$post['t']='ajax-response';
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/masssend";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 获取用户列表列表
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @param $groupid 分组id
-	 * @return array ({contacts:[{id:12345667,nick_name:"昵称",remark_name:"备注名",group_id:0},{}....]})
-	 */
-	function getUserList($page=0,$pagesize=10,$groupid=0){
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=".$pagesize."&pageidx=".$page."&type=0&groupid=0&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=".$pagesize."&pageidx=".$page."&type=0&groupid=$groupid&lang=zh_CN&f=json&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('userlist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['contact_list'])) {
-			$json = json_decode($json['contact_list'],true);
-			if (isset($json['contacts']))
-				return $json['contacts'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取分组列表
-	 * 
-	 */
-	function getGroupList(){
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&f=json&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('userlist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['group_list'])){
-			$json = json_decode($json['group_list'],true);
-			if (isset($json['groups']))
-				return $json['groups'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取图文信息列表
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @return array
-	 */
-	public function getNewsList($page,$pagesize=10) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$type=10;
-		$begin = $page*$pagesize;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/appmsg?token=".$this->_token."&lang=zh_CN&type=$type&action=list&begin=$begin&count=$pagesize&f=json&random=0.".$t;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('newslist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['app_msg_info'])) {
-			return $json['app_msg_info'];
-		} 
-		return false;
-	}
-	
-	/**
-	 * 获取与指定用户的对话内容
-	 * @param  $fakeid
-	 * @return  array
-	 */
-	public function getDialogMsg($fakeid) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=".$fakeid."&token=".$this->_token."&lang=zh_CN&f=json&random=".$t;
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('DialogMsg:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['page_info'])) {
-			return $json['page_info'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 发送图文信息,必须从图文库里选取消息ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $msgid 图文消息id
-	 */
-	public function sendNews($id,$msgid)
-	{
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = 10;
-		$post['token'] = $this->_token;
-		$post['fid'] = $msgid;
-		$post['appmsgid'] = $msgid;
-		$post['error'] = 'false';
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		return $send_snoopy->results;
-	}
-	
-	/**
-	 * 上传附件(图片/音频/视频)
-	 * @param string $filepath 本地文件地址
-	 * @param int $type 文件类型: 2:图片 3:音频 4:视频
-	 */
-	public function uploadFile($filepath,$type=2) {
-		$send_snoopy = new Snoopy;
-		$send_snoopy->referer = "http://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-upload&lang=zh_CN&type=2&formId=1";
-		$t = time().strval(mt_rand(100,999));
-		$post = array('formId'=>'');
-		$postfile = array('uploadfile'=>$filepath);
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->set_submit_multipart();
-		$submit = "http://mp.weixin.qq.com/cgi-bin/uploadmaterial?cgi=uploadmaterial&type=$type&token=".$this->_token."&t=iframe-uploadfile&lang=zh_CN&formId=	file_from_".$t;
-		$send_snoopy->submit($submit,$post,$postfile);
-		$tmp = $send_snoopy->results;
-		$this->log('upload:'.$tmp);
-		preg_match("/formId,.*?\'(\d+)\'/",$tmp,$matches);
-		if (isset($matches[1])) {
-			return $matches[1];
-		}
-		return false;
-	}
-	
-	/**
-	 * 创建图文消息
-	 * @param array $title 标题
-	 * @param array $summary 摘要
-	 * @param array $content 内容
-	 * @param array $photoid 素材库里的图片id(可通过uploadFile上传后获取)
-	 * @param array $srcurl 原文链接
-	 * @return json
-	 */
-	public function addPreview($title,$author,$summary,$content,$photoid,$srcurl='') {
-		$send_snoopy = new Snoopy;
-		$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&token='.$this->_token;
-		
-		$submit = "https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&t=ajax-response&sub=create&token=".$this->_token;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		
-		$send_snoopy->set_submit_normal();
-		$post = array(
-				'token'=>$this->_token,
-				'type'=>10,
-				'lang'=>'zh_CN',
-				'sub'=>'create',
-				'ajax'=>1,
-				'AppMsgId'=>'',				
-				'error'=>'false',
-		);
-		if (count($title)==count($author)&&count($title)==count($summary)&&count($title)==count($content)&&count($title)==count($photoid))
-		{
-			$i = 0;
-			foreach($title as $v) {
-				$post['title'.$i] = $title[$i];
-				$post['author'.$i] = $author[$i];
-				$post['digest'.$i] = $summary[$i];
-				$post['content'.$i] = $content[$i];
-				$post['fileid'.$i] = $photoid[$i];
-				if ($srcurl[$i]) $post['sourceurl'.$i] = $srcurl[$i];
-				
-				$i++;
-				}
-		}
-		$post['count'] = $i;
-		$post['token'] = $this->_token;
-		$send_snoopy->submit($submit,$post);
-		$tmp = $send_snoopy->results;
-		$this->log('step2:'.$tmp);
-		$json = json_decode($tmp,true);
-		return $json;
-	}
-	
-	/**
-	 * 发送媒体文件
-	 * @param $id 用户的uid(即FakeId)
-	 * @param $fid 文件id
-	 * @param $type 文件类型
-	 */
-	public function sendFile($id,$fid,$type) {
-		$send_snoopy = new Snoopy; 
-		$post = array();
-		$post['tofakeid'] = $id;
-		$post['type'] = $type;
-		$post['token'] = $this->_token;
-		$post['fid'] = $fid;
-		$post['fileid'] = $fid;
-		$post['error'] = 'false';
-		$post['ajax'] = 1;
-        $send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response";
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log('sendfile:'.$result);
-		$json = json_decode($result,true);
-		if ($json && $json['ret']==0) 
-			return true;
-		else
-			return false;
-	}
-	
-	/**
-	 * 获取素材库文件列表
-	 * @param $type 文件类型: 2:图片 3:音频 4:视频
-	 * @param $page 页码(从0开始)
-	 * @param $pagesize 每页大小
-	 * @return array
-	 */
-	public function getFileList($type,$page,$pagesize=10) {
-		$send_snoopy = new Snoopy;
-		$t = time().strval(mt_rand(100,999));
-		$begin = $page*$pagesize;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/filepage?token=".$this->_token."&lang=zh_CN&type=$type&random=0.".$t."&begin=$begin&count=$pagesize&f=json";
-		$send_snoopy->fetch($submit);
-		$result = $send_snoopy->results;
-		$this->log('filelist:'.$result);
-		$json = json_decode($result,true);
-		if (isset($json['page_info']))
-			return $json['page_info'];
-		else
-			return false;
-	}
-	
-	/**
-	 * 发送图文信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 文件id
-	 */
-	public function sendImage($id,$fid)
-	{
-		return $this->sendFile($id,$fid,2);
-	}
-	
-	/**
-	 * 发送语音信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 语音文件id
-	 */
-	public function sendAudio($id,$fid)
-	{
-		return $this->sendFile($id,$fid,3);
-	}
-	
-	/**
-	 * 发送视频信息,必须从库里选取文件ID发送
-	 * @param  string $id      用户的uid(即FakeId)
-	 * @param  string $fid 视频文件id
-	 */
-	public function sendVideo($id,$fid)
-	{
-		return $this->sendFile($id,$fid,4);
-	}
-	
-	/**
-	 * 发送预览图文消息
-	 * @param string $account 账户名称(user_name)
-	 * @param string $title 标题
-	 * @param string $summary 摘要
-	 * @param string $content 内容
-	 * @param string $photoid 素材库里的图片id(可通过uploadFile上传后获取)
-	 * @param string $srcurl 原文链接
-	 * @return json
-	 */
-	public function sendPreview($account,$title,$summary,$content,$photoid,$srcurl='') {
-		$send_snoopy = new Snoopy;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=preview&t=ajax-appmsg-preview";
-		$send_snoopy->set_submit_normal();
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&lang=zh_CN';
-		$post = array(
-				'AppMsgId'=>'',
-				'ajax'=>1,
-				'content0'=>$content,
-				'count'=>1,
-				'digest0'=>$summary,
-				'error'=>'false',
-				'fileid0'=>$photoid,
-				'preusername'=>$account,
-				'sourceurl0'=>$srcurl,
-				'title0'=>$title,
-		);
-		$post['token'] = $this->_token;
-		$send_snoopy->submit($submit,$post);
-		$tmp = $send_snoopy->results;
-		$this->log('sendpreview:'.$tmp);
-		$json = json_decode($tmp,true);
-		return $json;
-	}
-	
-	/**
-	 * 获取用户的信息
-	 * @param  string $id 用户的uid(即FakeId)
-	 * @return array  {fake_id:100001,nick_name:'昵称',user_name:'用户名',signature:'签名档',country:'中国',province:'广东',city:'广州',gender:'1',group_id:'0'},groups:{[id:0,name:'未分组',cnt:20]}
-	 */
-	public function getInfo($id)
-	{
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$t = time().strval(mt_rand(100,999));
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getcontactinfo";
-		$post = array('ajax'=>1,'lang'=>'zh_CN','random'=>'0.'.$t,'token'=>$this->_token,'t'=>'ajax-getcontactinfo','fakeid'=>$id);
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		$result = json_decode($send_snoopy->results,true);
-		if(isset($result['contact_info'])){
-			return $result['contact_info'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获得头像数据
-	 *
-	 * @param FakeId $fakeid
-	 * @return JPG二进制数据
-	 */
-	public function getHeadImg($fakeid){
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/misc/getheadimg?fakeid=$fakeid&token=".$this->_token."&lang=zh_CN";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('Head image:'.$fakeid.'; length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-
-	/**
-	 * 获取消息更新数目
-	 * @param int $lastid 最近获取的消息ID,为0时获取总消息数目
-	 * @return int 数目
-	 */
-	public function getNewMsgNum($lastid=0){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getnewmsgnum?t=ajax-getmsgnum&lastmsgid=".$lastid;
-		$post = array('ajax'=>1,'token'=>$this->_token);
-		$send_snoopy->submit($submit,$post);
-		$this->log($send_snoopy->results);
-		$result = json_decode($send_snoopy->results,1);
-		if(!$result){
-			return false;
-		}
-		return intval($result['newTotalMsgCount']);
-	}
-	
-	/**
-	 * 获取最新一条消息
-	 * @return array {"id":"最新一条id","type":"类型号(1为文字,2为图片,3为语音)","fileId":"0","hasReply":"0","fakeId":"用户uid","nickName":"昵称","dateTime":"时间戳","content":"文字内容","playLength":"0","length":"0","source":"","starred":"0","status":"4"}        
-	 */
-	public function getTopMsg(){
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$this->log($send_snoopy->results);
-		$result = $send_snoopy->results;
-		$json = json_decode($result,true);
-		if (isset($json['msg_items'])) {
-			$json = json_decode($json['msg_items'],true);
-			if(isset($json['msg_item']))
-				return array_shift($json['msg_item']);
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取新消息
-	 * @param $lastid 传入最后的消息id编号,为0则从最新一条起倒序获取
-	 * @param $offset lastid起算第一条的偏移量
-	 * @param $perpage 每页获取多少条
-	 * @param $day 最近几天消息(0:今天,1:昨天,2:前天,3:更早,7:五天内)
-	 * @param $today 是否只显示今天的消息, 与$day参数不能同时大于0
-	 * @param $star 是否星标组信息
-	 * @return array[] 同getTopMsg()返回的字段结构相同
-	 */
-	public function getMsg($lastid=0,$offset=0,$perpage=20,$day=7,$today=0,$star=0){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&lang=zh_CN&count=50&token=".$this->_token;
-		$lastid = $lastid===0 ? '':$lastid;
-		$addstar = $star?'&action=star':'';
-		$submit = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&lang=zh_CN{$addstar}&count=$perpage&timeline=$today&day=$day&frommsgid=$lastid&offset=$offset&token=".$this->_token;
-		$send_snoopy->fetch($submit);
-		$this->log($send_snoopy->results);
-		$result = $send_snoopy->results;
-		$json = json_decode($result,true);
-		if (isset($json['msg_items'])) {
-			$json = json_decode($json['msg_items'],true);
-			if(isset($json['msg_item']))
-				return $json['msg_item'];
-		}
-		return false;
-	}
-	
-	/**
-	 * 获取图片消息
-	 * @param int $msgid 消息id
-	 * @param string $mode 图片尺寸(large/small)
-	 * @return jpg二进制文件
-	 */
-	public function getMsgImage($msgid,$mode='large'){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/getimgdata?token=".$this->_token."&msgid=$msgid&mode=$mode&source=&fileId=0";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('msg image:'.$msgid.';length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-	
-	/**
-	 * 获取语音消息
-	 * @param int $msgid 消息id
-	 * @return mp3二进制文件
-	 */
-	public function getMsgVoice($msgid){
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/getvoicedata?token=".$this->_token."&msgid=$msgid&fileId=0";
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		$this->log('msg voice:'.$msgid.';length:'.strlen($result));
-		if(!$result){
-			return false;
-		}
-		return $result;
-	}
-
-	/**
-	 * 开启开发者模式
-	 */
-	public function openDevModel()
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN";
-		$post['flag']=1;
-        $post['type']=2;   
-        $post['token']=$this->_token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if(!$result){
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 关闭编辑模式
-	 */
-	public function closeEditModel()
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN";
-		$post['flag']=0;
-        $post['type']=1;   
-        $post['token']=$this->_token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if(!$result){
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 配置接口信息
-	 * @param  string $url      接口回调URL
-	 * @param  string $token    接口Token
-	 */
-	public function setUrlToken($url, $token)
-	{
-		$send_snoopy = new Snoopy;
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/interface&lang=zh_CN&token=".$this->_token;
-		$submit = "https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&lang=zh_CN&token=".$this->_token;
-		$post['url'] = $url;
-		$post['callback_token'] = $token;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		$this->log($send_snoopy->results);
-		$json = json_decode($result,true);
-		if ($json && $json['ret']==0) 
-			return true;
-		return false;
-	}
-
-	/**
-	 * 快速设置接口
-	 * @param  string $url      接口回调URL
-	 * @param  string $token    接口Token
-	 */
-	public function quickSetInterface($url, $token)
-	{
-		if ($this->closeEditModel() && $this->openDevModel() && $this->setUrlToken($url, $token))
-			return true;
-		return false;
-	}
-
-	/**
-	 * 获取公众账号基本信息
-	 * @param  [string] $dir [指定相对于网站根目录的下载路径,因为需要下载二维码和用户头像]
-	 * @return [array]       [公众账号信息,其中包含:nickname,avatar,type,qrcode,appid,appsecret]
-	 */
-	public function getCommonInfo($dir)
-	{
-		$userInfo = array();
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		// 分析首页内容,获取nickname,avatar,usertype
-		preg_match_all('/class=\"nickname\">(.*)<\/a>/', $result, $matches1);
-        preg_match_all('/<img src=\"(.*)\" class=\"avatar\"/', $result, $matches2);
-        preg_match_all('/<label for=\"\" class=\"type icon_service_label\">(.*)<\/label>/', $result, $matches3);
-        $userInfo["nickname"] = $nickname = $matches1[1][0];
-        if(strpos($nickname, '<') !== false)
-        {
-        	$userInfo["nickname"] = $nickname = substr($nickname, 0, strpos($nickname, '<'));
-        }
-        $userInfo["avatar"] = $avatar = $matches2[1][0];
-        if( ! empty($matches3[1][0]))
-        {
-            $userInfo["type"] = $usertype = $matches3[1][0];
-        }
-        else
-        {
-            $userInfo["type"] = $usertype = "订阅号";
-        }
-		$this->log('Analysis account info:'. "\nNickname:". $nickname. "\nAvatar:". $avatar. "\nUsertype:". $usertype);
-		// 分析设置页面,获取二维码
-		$send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-		// $this->log("QRCODE contents:". $result);
-		preg_match_all('/<img src=\"(.*)\" width=\"150\"/', $result, $matches4);
-        $userInfo["qrcode"] = $qrcode = $matches4[1][0];
-        // downloads the avatar
-        $send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com". $avatar;
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-        $userInfo["avatar"] = $this->downloadImage($result, $dir. DIRECTORY_SEPARATOR. 'avatars');
-        // downloads the qrcode
-        $send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com". $qrcode;
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-        $userInfo["qrcode"] = $this->downloadImage($result, $dir. DIRECTORY_SEPARATOR. 'qrcodes');
-        // 获取appid和appsecret
-        $send_snoopy = new Snoopy; 
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->referer = "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=".$this->_token;
-		$url = "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=".$this->_token;
-		$send_snoopy->fetch($url);
-		$result = $send_snoopy->results;
-
-		preg_match_all('/name:\"AppId\",value:\"(.*)\"/', $result, $matches_id);
-		preg_match_all('/name:\"AppSecret\",value:\"(.*)\"/', $result, $matches_secret);
-		
-        $userInfo["appid"] = $AppId = $matches_id[1][0];
-        $userInfo["appsecret"] = $AppSecret = $matches_secret[1][0];
-        
-		if(! empty($userInfo)){
-			return $userInfo;
-		}
-		return false;
-	}
-
-	/**
-	 * 下载图片资源
-	 * @param  [string] $from    [资源链接]
-	 * @param  [string] $dir     [相对于网站根目录]
-	 * @return [string]          [返回相对地址]
-	 */
-	public function downloadImage($from, $dir)
-	{
-	    $random_name =  str_replace('.', '', microtime(true)). rand(2, 10000);
-	    if( ! is_dir($dir))
-	    {
-	    	mkdir($dir, 0755, true);	
-	    }
-	    $savefile = preg_replace('/[\\\\\/]+/', DIRECTORY_SEPARATOR, $dir. '/'. $random_name);
-	    file_put_contents($savefile, $from);
-	    $filesize = filesize($savefile);
-	    $avatar_type = $this->checkImgType($savefile);
-	    if ($filesize <= 0 || $avatar_type=='unknown') 
-	    {
-	        unlink($savefile);
-	    }
-	    exec("mv $savefile ". $savefile. '.'. $avatar_type);
-	    return $dir. '/'. $random_name. '.'. $avatar_type;
-	}
-
-	/**
-	 * 检测图片类型
-	 * @param  [string] $imgName [文件路径]
-	 * @return [string]          [文件类型]
-	 */
-	public function checkImgType($imgName){
-	    $file = fopen($imgName, "rb");
-	    $bin = fread($file, 2);
-	    $strInfo  = @unpack("C2chars", $bin);
-	    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
-	    switch($typeCode)
-	    {
-	        case '255216':
-	            return 'jpg';
-	            break;
-	        case '7173':
-	            return 'gif';
-	            break;
-	        case '13780':
-	            return 'png';
-	            break;
-	        case '6677':
-	            return 'bmp';
-	            break;
-	        default:
-	            return 'unknown';
-	            break;
-	    }
-	}
-	
-	/**
-	 * 模拟登录获取cookie
-	 * @return [type] [description]
-	 */
-	public function login(){
-		$snoopy = new Snoopy; 
-		$submit = "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN";
-		$post["username"] = $this->_account;
-		$post["pwd"] = md5($this->_password);
-		$post["f"] = "json";
-		$post["imgcode"] = "";
-		$snoopy->referer = "https://mp.weixin.qq.com/";
-		$snoopy->submit($submit,$post);
-		$cookie = '';
-		$this->log($snoopy->results);
-		$result = json_decode($snoopy->results,true);
-		
-		if (!isset($result['base_resp']) || $result['base_resp']['ret'] != 0) {
-			return false;
-		}
-        
-		foreach ($snoopy->headers as $key => $value) {
-			$value = trim($value);
-			if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $value,$match))
-				$cookie .=$match[1].'='.$match[2].'; ';
-		}
-		
-		preg_match("/token=(\d+)/i",$result['redirect_url'],$matches);
-		if($matches){
-			$this->_token = $matches[1];
-			$this->log('token:'.$this->_token);
-		}
-		$cookies='{"cookie":"'.$cookie.'","token":"'.$this->_token.'"}';
-		$this->saveCookie($this->_cookiename,$cookies);
-		return $cookie;
-	}
-
-	/**
-	 * 把cookie写入缓存
-	 * @param  string $filename 缓存文件名
-	 * @param  string $content  文件内容
-	 * @return bool
-	 */
-	public function saveCookie($filename,$content){
-		return file_put_contents($filename,$content);
-	}
-
-	/**
-	 * 读取cookie缓存内容
-	 * @param  string $filename 缓存文件名
-	 * @return string cookie
-	 */
-	public function getCookie($filename){
-		if (file_exists($filename)) {
-			$mtime = filemtime($filename);
-			if ($mtime<time()-$this->_cookieexpired) 
-				$data = '';
-			else
-				$data = file_get_contents($filename);
-		} else
-			$data = '';
-		if($data){
-			$login=json_decode($data,true);
-			$send_snoopy = new Snoopy;
-			$send_snoopy->rawheaders['Cookie']= $login['cookie'];
-			$send_snoopy->maxredirs = 0;
-			$url = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=".$login['token'];
-			$send_snoopy->fetch($url);
-			$header = $send_snoopy->headers;
-			$this->log('header:'.print_r($send_snoopy->headers,true));
-			if( strstr($header[3], 'EXPIRED')){
-				return $this->login();
-			}else{
-				$this->_token =$login['token'];
-				$this->log('token:'.$this->_token);
-				return $login['cookie'];
-			}
-		}else{
-			return $this->login();
-		}
-	}
-
-	/**
-	 * 验证cookie的有效性
-	 * @return bool
-	 */
-	public function checkValid()
-	{
-		if (!$this->cookie || !$this->_token) return false;
-		$send_snoopy = new Snoopy; 
-		$post = array('ajax'=>1,'token'=>$this->_token);
-		$submit = "https://mp.weixin.qq.com/cgi-bin/getregions?id=1017&t=ajax-getregions&lang=zh_CN";
-		$send_snoopy->rawheaders['Cookie']= $this->cookie;
-		$send_snoopy->submit($submit,$post);
-		$result = $send_snoopy->results;
-		if(json_decode($result,1)){
-			return true;
-		}else{
-			return false;
-		}
-	}
-	
-	private function log($log){
-		if ($this->debug && function_exists($this->_logcallback)) {
-			if (is_array($log)) $log = print_r($log,true);
-			return call_user_func($this->_logcallback,$log);
-		}
-	}
-	
-}

+ 15 - 11
wiki/Home.md

@@ -22,25 +22,29 @@
     > 调用官方API,具有更灵活的消息分类响应方式,支持链式调用操作 ;
 
  - [[企业号API类库]]
-    > qywechat.class.php 
+    > qywechat.class.php
     > 微信公众平台企业号PHP-SDK
     > 调用官方API,具有更灵活的消息分类响应方式,支持链式调用操作 ;
 
- - [[非官方扩展类库]]
-    > wechatext.class.php 
+ - [[API接口错误码]]
+    > errCode.php 或 qyerrCode.php
+    > 当调用API接口失败时,可以用此类来换取失败原因的中文说明。
+
+ - [[旧版微信支付V2接口类库]]
+    > old_version/wechatpay.class.php
+    > 当调用API接口失败时,可以用此类来换取失败原因的中文说明。
+
+ - ~~[[非官方扩展类库]]~~*(停止维护)*
+    > old_version/wechatext.class.php
     > 非官方扩展API,模拟人工操作微信平台,此方式不保证长期有效。  
 
- - [[授权登陆类库]]
-    > wechatauth.class.php  
+ - ~~[[授权登陆类库]]~~*(停止维护)*
+    > old_version/wechatauth.class.php
     > 通过微信二维码登陆微信的API, 能实现第三方网站同步登陆
 
- - [[内嵌JS]]
-    > wechat.js
+ - ~~[[内嵌JS]]~~*(已废弃)*
+    > old_version/wechat.js
     > 微信内嵌网页功能调用js
 
- - [[API接口错误码]]
-    > errCode.php 或 qyerrCode.php 
-    > 当调用API接口失败时,可以用此类来换取失败原因的中文说明。
-
 
 

+ 1 - 0
wiki/企业号API类库.md

@@ -116,6 +116,7 @@ $options = array(
 > 0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加
 * getUserListInfo($department_id,$fetch_child=0,$status=0) 获取部门成员详情,参数同上
 * getUserId($code,$agentid) 根据code获取员工UserID与手机设备号,参数:Oauth2.0或者二次验证返回的code值,跳转链接时所在的企业应用ID
+* sendInvite($userid,$invite_tips='') 邀请成员关注
 * createTag($data) 创建标签,参数:array("tagname" => "UI")
 * updateTag($data) 更新标签,参数:array("tagid" => "1","tagname" => "UI")
 * deleteTag($tagid) 删除标签,参数:标签TagID

+ 2 - 0
wiki/内嵌JS.md

@@ -1,5 +1,7 @@
 #wechat.js
 
+**此JS脚本已经废弃不再更新,原因是官方在微信6.0.2版本开放了全新的JSAPI接口,更全面好用。请查看:[微信公众平台WIKI](http://mp.weixin.qq.com/wiki)**
+
 ##微信内嵌网页特殊功能js调用:
  * WeixinJS.hideOptionMenu() 隐藏右上角按钮
  * WeixinJS.showOptionMenu() 显示右上角按钮

+ 3 - 17
wiki/官方API类库.md

@@ -14,17 +14,12 @@
 - 用户信息(查询用户基本信息、获取关注者列表) **(认证权限)**
 - 多客服功能(客服管理、获取客服记录、客服会话管理) **(认证权限)**
 - 媒体文件(上传、获取) **(认证权限)**
-- 调用地址组件 **(支付权限)**
-- 生成订单签名数据 **(支付权限)**
-- 订单成功回调 **(支付权限)**
-- 发货通知 **(支付权限)**
-- 支付订单查询 **(支付权限)**
 - 高级群发 **(认证权限)**
 - 模板消息(设置所属行业、添加模板、发送模板消息) **(服务号、认证权限)**
 - 卡券管理(创建、修改、删除、发放、门店管理等) **(认证权限)**
 - 语义理解 **(服务号、认证权限)**
 - 获取微信服务器IP列表 **(初级权限)**  
-- 微信JSAPI授权(获取ticket、获取签名) **(初级权限`暂未确定`)**
+- 微信JSAPI授权(获取ticket、获取签名) **(初级权限)**
 > 备注:  
 > 初级权限:基本权限,任何正常的公众号都有此权限  
 > 菜单权限:正常的服务号、认证后的订阅号拥有此权限  
@@ -38,10 +33,7 @@
 	'token'=>'tokenaccesskey', //填写你设定的key
 	'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey
 	'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询
-	'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
-	'partnerid'=>'88888888', //财付通商户身份标识,支付权限专用,没有可不填
-	'partnerkey'=>'', //财付通商户权限密钥Key,支付权限专用
-	'paysignkey'=>'' //商户签名密钥Key,支付权限专用
+	'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥
 	);
  $weObj = new Wechat($options); //创建实例对象
  //TODO:调用$weObj各实例方法
@@ -164,13 +156,7 @@
  *  getOauthUserinfo($access_token,$openid) 通过网页授权的access_token获取用户资料  
  *  getOauthAuth($access_token,$openid)  检验授权凭证access_token是否有效
  *  getSignature($arrdata,'sha1') 生成签名字串  
- *  generateNonceStr($length) 获取随机字串  
- *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type="WX",$input_charset="UTF-8",$time_start="",$time_expire="",$transport_fee="",$product_fee="",$goods_tag="",$attach="") 生成订单package字符串  
- *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  
- *  checkOrderSignature($orderxml='') 回调通知签名验证  
- *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  
- *  getPayOrder($out_trade_no) 查询订单信息  
- *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名
+ *  generateNonceStr($length=16) 获取随机字串  
  *  setTMIndustry($id1,$id2='') 模板消息,设置所属行业
  *  addTemplateMessage($tpl_id) 模板消息,添加消息模板
  *  sendTemplateMessage($data) 发送模板消息

+ 2 - 0
wiki/授权登陆类库.md

@@ -1,5 +1,7 @@
 # wechatauth.class.php  
 
+*此扩展类库已经不再更新,原因是官方开放平台对网站应用开放的有授权登陆接口,更标准,更好用*请查看:[微信开放平台](http://open.weixin.qq.com)
+
 通过微信二维码登陆微信的API, 能实现第三方网站同步登陆, 首先程序分别通过get_login_code和get_code_image方法获取授权二维码图片, 然后利用微信手机客户端扫描二维码图片后将自动跳出授权页面, 用户点击授权后即可获取对应的用户资料和头像信息. 详细验证步骤请看test3.php例子.   
 
 ## 类主要方法:

+ 45 - 0
wiki/旧版微信支付V2接口类库.md

@@ -0,0 +1,45 @@
+# wechatpay.class.php 
+
+旧版微信支付类库(微信支付V2),已移动至old_version目录下。
+自2014年8月开始申请到的微信支付都是V3接口,据官方说V2的会陆续升级为V3接口,但时间及升级渠道未确认。
+
+### 主要功能 
+- 获取access_token **(初级权限)**
+- 调用地址组件 **(支付权限)**
+- 生成订单签名数据 **(支付权限)**
+- 订单成功回调 **(支付权限)**
+- 发货通知 **(支付权限)**
+- 支付订单查询 **(支付权限)**
+> 备注:  
+> 初级权限:基本权限,任何正常的公众号都有此权限  
+> 菜单权限:正常的服务号、认证后的订阅号拥有此权限  
+> 认证权限:分为订阅号、服务号认证,如前缀服务号则仅认证的服务号有此权限,否则为认证后的订阅号、服务号都有此权限  
+> 支付权限:仅认证后的服务号可以申请此权限  
+
+
+### 初始化动作 
+```php
+ $options = array(
+	'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询
+	'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
+	'partnerid'=>'88888888', //财付通商户身份标识,支付权限专用,没有可不填
+	'partnerkey'=>'', //财付通商户权限密钥Key,支付权限专用
+	'paysignkey'=>'' //商户签名密钥Key,支付权限专用
+	);
+ $weObj = new Wechat($options); //创建实例对象
+ //TODO:调用$weObj各实例方法
+```
+
+### 主动接口方法:   
+ *  checkAuth($appid='',$appsecret='',$token='') 获取access_token。可根据appid和appsecret获取,或手动指定access_token
+ *  resetAuth($appid='') 删除验证数据
+ *  getSignature($arrdata,'sha1') 生成签名字串  
+ *  generateNonceStr($length) 获取随机字串  
+ *  createNativeUrl($productid) 生成原生支付url
+ *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type="WX",$input_charset="UTF-8",$time_start="",$time_expire="",$transport_fee="",$product_fee="",$goods_tag="",$attach="") 生成订单package字符串  
+ *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  
+ *  checkOrderSignature($orderxml='') 回调通知签名验证  
+ *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  
+ *  getPayOrder($out_trade_no) 查询订单信息  
+ *  setUserToken($user_token) 设置用户授权密钥
+ *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名

+ 2 - 0
wiki/非官方扩展类库.md

@@ -1,5 +1,7 @@
 # wechatext.class.php
 
+**此扩展类库已经不再更新,原因是官方对公众号开放了众多接口,此类库继续维护的意义不大**
+
 非官方扩展API,需要配置公众平台账户和密码,能实现对已关注用户的点对点微信,此方式不保证长期有效。  
 类方法里提及的用户id在接口返回结构里表述为FakeId, 属同一概念, 在下面wechatauth类里则表示为Uin, 用户id对应的微信号必须通过getInfo()方法通过返回数组的Username值获取, 但非关注关系用户资料不能获取.  
 调用下列方法前必须经过login()方法和checkValid()验证方法才能获得调用权限. 有的账户无法通过登陆可能因为要求提供验证码, 可以手动登陆后把获取到的cookie写进程序存放cookie的文件解决.