Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
576 lines (526 sloc) 19.5 KB
<?php
/**
* 个人微信公众号 通信入口
* sobird
* OpenID gh_bcacb6724981
*
* @author junlong.yang at 2013-4-10 PM12:52:57 build
* @link http://dev.sobird.me/
*/
class indexAction extends C {
/**
* 接收到的微信消息对象, 由xml解析而来
*
* @var object
*/
private $wxMsgBody = null;
/**
* 接受到的消息类型,默认text类型
*
* 目前有如下几种类型:
* text, image, voice, video, shortvideo, location, link
*
* @since 20130411
* @var string
*/
private $wxMsgType = 'text';
/**
* 模拟文本消息数据
*
* @example
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType text
* Content 文本消息内容
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockTextData = '<xml>
<ToUserName><![CDATA[gh_bcacb6724981]]></ToUserName>
<FromUserName><![CDATA[ojtXSjqsoTjE52PwniNpbVSkd]]></FromUserName>
<CreateTime>1365606056</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test text msg~~]]></Content>
<MsgId>11</MsgId>
</xml>';
/**
* 模拟图片信息数据
*
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType image
* PicUrl 图片链接(由系统生成)
* MediaId 图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockImageData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[this is a url]]></PicUrl>
<MediaId><![CDATA[media_id]]></MediaId>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 模拟语音消息
*
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 语音为voice
* MediaId 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
* Format 语音格式,如amr,speex等
* MsgID 消息id,64位整型
* @var string
*/
private $mockVoiceData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 模拟视频消息
*
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 视频为video
* MediaId 视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
* ThumbMediaId 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockVideoData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 模拟微信小视频消息
*
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 小视频为shortvideo
* MediaId 视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
* ThumbMediaId 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockShortvideoData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[shortvideo]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 模拟微信地理位置消息
*
* ToUserName 开发者微信号
* FromUserName 发送方帐号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType location
* Location_X 地理位置维度
* Location_Y 地理位置经度
* Scale 地图缩放大小
* Label 地理位置信息
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockLocationData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>23.134521</Location_X>
<Location_Y>113.358803</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[位置信息]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 模拟微信链接信息
*
* ToUserName 接收方微信号
* FromUserName 发送方微信号,若为普通用户,则是一个OpenID
* CreateTime 消息创建时间
* MsgType 消息类型,link
* Title 消息标题
* Description 消息描述
* Url 消息链接
* MsgId 消息id,64位整型
*
* @var string
*/
private $mockLinkData = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA[公众平台官网链接]]></Title>
<Description><![CDATA[公众平台官网链接]]></Description>
<Url><![CDATA[url]]></Url>
<MsgId>1234567890123456</MsgId>
</xml>';
/**
* 微信网址接口接入验证
*
* @method GET
* @see http://mp.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E6%8C%87%E5%8D%97
*
* @param String $signature 微信加密签名
* @param String $timestamp 时间戳
* @param String $nonce 随机数
* @param String $echostr 随机字符串
* @param String $test 本地测试参数
* @return void
*/
function onHttpRequest($signature, $timestamp, $nonce, $echostr, $debug) {
if($this->checkSignature($signature, $timestamp, $nonce)) {
exit($echostr);
} else {
// 微信网址接入认证失败
}
//本地测试代码, 兼容线上环境 可上线
if(!empty($debug)) {
$this->onHttpPostRequest($this->mockLocationData);
}
}
/**
* 验证微信网址接入
*
* @param String $signature 微信加密签名
* @param String $timestamp 时间戳
* @param String $nonce 随机数
* @return boolean
*/
private function checkSignature($signature, $timestamp, $nonce){
$tmp_array = array($this->token, $timestamp, $nonce);
sort($tmp_array);
$tmp_str = implode($tmp_array);
$tmp_str = sha1($tmp_str);
if( $tmp_str == $signature ){
return true;
}else{
return false;
}
}
/**
* 微信消息接收入口
*
* @method POST
*/
function onHttpPostRequest($mock){
$wxMsgBody = $mock;
if(empty($wxMsgBody)){
$wxMsgBody = file_get_contents("php://input");
}
$this->wxMsgBody = simplexml_load_string($wxMsgBody, 'SimpleXMLElement', LIBXML_NOCDATA);
$this->wxMsgType = strtoupper($this->wxMsgBody->MsgType);
$msg = (array)$this->wxMsgBody;
switch ($this->wxMsgType){
// 文本消息 大部分情况都是文本消息 语言类型~~
case 'TEXT' :
$this->resolveTextMsg($msg);
break;
case 'IMAGE' :
$this->resolveImageMsg($msg);
break;
case 'VOICE' :
$this->resolveVoiceMsg($msg);
break;
case 'VIDEO' :
$this->resolveVideoMsg($msg);
break;
case 'SHORTVIDEO' :
$this->resolveShortvideoMsg($msg);
break;
case 'LOCATION' :
$this->resolveLocationMsg($msg);
break;
case 'LINK' :
$this->resolveLinkMsg($msg);
break;
case 'EVENT' :
break;
default:
}
// 中文自然语言学习~~
$this->fire('learn', $this->wxMsgBody, $this->wxMsgType);
$this->comet();
}
/**
* 处理并响应微信文本消息
*
* 消息结构:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>1348831860</CreateTime>
* <MsgType><![CDATA[text]]></MsgType>
* <Content><![CDATA[this is a test]]></Content>
* <MsgId>1234567890123456</MsgId>
* </xml>
*
*/
function resolveTextMsg($msg){
try {
$msg = $this->wechatModel->saveTextMsg($msg);
} catch(Exception $e){
//TODO
}
//TODO
}
/**
* 处理并响应微信图片信息
*
* 信息结构:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>1348831860</CreateTime>
* <MsgType><![CDATA[image]]></MsgType>
* <PicUrl><![CDATA[this is a url]]></PicUrl>
* <MsgId>1234567890123456</MsgId>
* </xml>
*
* @param [Object] $msg_obj
*/
function resolveImageMsg($msg){
try {
//数据存库操作
$msg = $this->wechatModel->saveImageMsg($msg);
} catch(Exception $e){
//TODO
}
}
function resolveVoiceMsg($msg){
try {
//数据存库操作
$msg = $this->wechatModel->saveVoiceMsg($msg);
} catch(Exception $e){
//TODO
}
}
function resolveVideoMsg($msg){
try {
//数据存库操作
$msg = $this->wechatModel->saveVideoMsg($msg);
} catch(Exception $e){
//TODO
}
}
function resolveShortvideoMsg($msg){
try {
//数据存库操作
$msg = $this->wechatModel->saveShortvideoMsg($msg);
} catch(Exception $e){
//TODO
}
}
/**
* 处理并响应地理位置消息
*
* 消息结构:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>1351776360</CreateTime>
* <MsgType><![CDATA[location]]></MsgType>
* <Location_X>23.134521</Location_X>
* <Location_Y>113.358803</Location_Y>
* <Scale>20</Scale>
* <Label><![CDATA[位置信息]]></Label>
* <MsgId>1234567890123456</MsgId>
* </xml>
*
* @param [Object] $msg_obj
*/
function resolveLocationMsg($msg){
try {
//数据存库操作
$msg = $this->wechatModel->saveLocationMsg($msg);
} catch(Exception $e){
//TODO
}
}
/**
* 处理并响应链接消息
*
* 消息结构:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>1351776360</CreateTime>
* <MsgType><![CDATA[link]]></MsgType>
* <Title><![CDATA[公众平台官网链接]]></Title>
* <Description><![CDATA[公众平台官网链接]]></Description>
* <Url><![CDATA[url]]></Url>
* <MsgId>1234567890123456</MsgId>
* </xml>
*
* @param [Object] $msg_obj
*/
function resolveLinkMsg($msg_arr){
try {
//数据存库操作
$msg = $this->wechatModel->saveLinkMsg($msg_arr);
} catch(Exception $e){
//TODO
}
}
/**
* 处理并响应微信事件消息 事件推送
*
* 消息结构:
* <xml><ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[EVENT]]></Event>
* <EventKey><![CDATA[EVENTKEY]]></EventKey>
* </xml>
*
* 参数 描述
* -------------------------------------------------------------------------------------------
* ToUserName 接收方微信号
* FromUserName 发送方微信号,若为普通用户,则是一个OpenID
* CreateTime 消息创建时间
* MsgType 消息类型,event
* Event 事件类型,subscribe(订阅)、unsubscribe(取消订阅)、CLICK(自定义菜单点击事件)
* EventKey 事件KEY值,与自定义菜单接口中KEY值对应
*
* @param [Object] $msg_obj
*/
function resolve_event_msg($msg_arr){
try {
//数据存库操作
$msg = $this->wechatModel->insert_r_event_msg($msg_arr);
} catch(Exception $e){
//TODO
}
$event_type = strtoupper($msg_arr['Event']);
switch ($event_type){
//关注
case 'SUBSCRIBE' :
$this->on_subscribe($msg_arr);
break;
//取消关注
case 'UNSUBSCRIBE' :
$this->on_unsubscribe($msg_arr);
break;
//自定义菜单点击事件
case 'CLICK' :
$this->on_click_menu($msg_arr);
break;
default:
}
}
//用户关注事件触发句柄函数
function on_subscribe($msg_arr){
try {
//数据存库操作
$data = array(
'FromUserName' => $msg_arr['FromUserName'],
'ToUserName' => $msg_arr['ToUserName'],
'subscribe' => '1',
'LastTime' => $msg_arr['CreateTime']
);
$from_user_name = $msg_arr['FromUserName'];
$this->wechatModel->save_follow_user($data, $from_user_name);
} catch(Exception $e){
//TODO
}
//TODO
}
//用户取消关注事件触发句柄函数
function on_unsubscribe($msg_arr){
try {
//数据存库操作
$data = array(
'FromUserName' => $msg_arr['FromUserName'],
'ToUserName' => $msg_arr['ToUserName'],
'subscribe' => '0',
'LastTime' => $msg_arr['CreateTime']
);
$from_user_name = $msg_arr['FromUserName'];
$this->wechatModel->save_follow_user($data, $from_user_name);
} catch(Exception $e){
//TODO
}
//TODO
}
//用户点击自定义菜单事件句柄函数
function on_click_menu($msg_arr){
//TODO 暂不处理该类型的事件~~
}
//该动作被触发~~
function onFire($param){
//TODO
}
public function comet() {
$cometfile = WWW_PATH . 'wechat.comet';
if(!file_exists($cometfile)) {
file_put_contents($cometfile, '');
}
$filemtime = filemtime($cometfile);
$timing = time() - $filemtime;
$wxMsgBody = (array)$this->wxMsgBody;
$FromUserName = $wxMsgBody['FromUserName'];
//$userInfo = $this->wechatModel->getUserInfo($FromUserName);
//$wxMsgBody['userInfo'] = $userInfo;
if($timing > 1) {
file_put_contents($cometfile, serialize($wxMsgBody));
} else {
file_put_contents($cometfile, serialize($wxMsgBody) . PHP_EOL, FILE_APPEND);
}
}
/**
* 数组转XML
*
* @param array $array
* @return xml
*/
public function array2xml($array) {
function arrParse($xml, $data){
foreach($data as $key => $value){
if(is_array($value)){
$xml->startElement($key);
arrParse($xml,$value);
$xml->endElement();
continue;
}
$xml->writeElement($key, $value);
}
}
$xml = new XmlWriter();
$xml->openMemory();
//$xml->startDocument('1.0', 'utf-8');
$xml->startElement('xml');
arrParse($xml, $array);
$xml->endElement();
return $xml->outputMemory(true);
}
}
/* End of file: indexAction.class.php*/
/* Location: ./indexAction.class.php*/