token = $wxConfig['token'];
$this->appid = $wxConfig['appid'];
$this->appsecret = $wxConfig['appsecret'];
}
/**
* Des:接收参数并处理返回值
* Name: exec
* @return string
* @author 倪宗锋
*/
public function exec()
{
$content = $this->getContent();//获取参数并解析
if ($content['MsgType'] == 'text') {
$this->response = $this->textMsg($content);
} elseif ($content['MsgType'] == 'event') {
$this->response = $this->eventMsg($content);
}
return $this->response;
}
/**
* Des:用户输入内容处理
* Name: textMsg
* @param $content
* @return bool|string
* @author 倪宗锋
*/
public function textMsg($content)
{
// $textTpl = "
//
//
//
//%s
//
//";
// $resultStr = sprintf($textTpl, $content['FromUserName'], $content['ToUserName'], time());
// return $resultStr;
$word = $content['Content'];
return $this->send($word, $content, 'text');
}
/**
* Des:推送事件处理
* Name: eventMsg
* @param $content
* @return string
* @author 倪宗锋
*/
public function eventMsg($content)
{
if ($content['Event'] == 'subscribe') {//微信关注事件 发送欢迎语
$word = 'subscribe';
} elseif ($content['Event'] == 'unsubscribe') {//微信关注事件 发送欢迎语
$word = 'unsubscribe';
} elseif ($content['Event'] == 'SCAN') {//扫一扫
$word = 'SCAN';
} else if ($content['Event'] == 'VIEW' || empty($content['EventKey'])) {
return false;
} else {
$word = $content['EventKey'];
}
if ($word == 'MSG_LIANXIKEFU') {
return $this->callCuster($content);
}
return $this->send($word, $content, 'event');
}
/**
* Des:联系客服
* Name: sendText
* @param $content
* @return string
* @author 倪宗锋
*/
private function callCuster($content)
{
$textTpl = '' . "
%s
";
$resultStr = sprintf($textTpl, $content['FromUserName'], $content['ToUserName'], time());
return $resultStr;
}
/**
* Des: 发送处理
* Name: send
* @param $word
* @param $content
* @param string $type 触发类型:text用户输入 event推送事件
* @return string
* @author 倪宗锋
*/
public function send($word, $content, $type = 'text')
{
$weChatPayConfig = Util::getWeChatConfig();
$textConfig = require ROOT_PATH . '/common/config/wechatConfig/wxInterface/' . $weChatPayConfig['mch_id'] . '/Wx.' . $type . '.config.php';
if (empty($textConfig[$word]) == false) {//如果 有指定的配置就用指定的配置
$msgSend = $textConfig[$word];
} else if ($type == 'text') {//没有指定的配置 且 接收的是用户输入文本信息
// $info = new WxDoFunction();
// $getDoResult = $info->showOrderInfo($word);//获取订单信息暂时停止 //todo 获取订单信息
// if ($getDoResult == '') {
// //默认联系客服
// $msgSend = $this->callCuster($content);
// return $msgSend;
// } else {
// $msgSend = $getDoResult;
// }
//默认联系客服
$msgSend = $this->callCuster($content);
return $msgSend;
} else {//没有指定配置 且接收的是按钮或扫一扫则直接返回关注自动回复信息
$msgSend = $textConfig['subscribe'];
}
if (is_array($msgSend) && empty($msgSend['function']) == false) {//当推送事件有方法指定时,则调用该方法
$wxDoFunction = new WxDoFunction();
$function = $msgSend['function'];
$wxDoFunction->$function($content);
}
if (isset($msgSend['type']) && $msgSend['type'] == 'news') {//如果是图文类型
return $this->sendNews($content, $msgSend['id']);
} elseif (isset($msgSend['type']) && $msgSend['type'] == 'img') {//如果是图片类型
return $this->sendImage($content, $msgSend['id']);
} elseif (isset($msgSend['type']) && $msgSend['type'] == 'voice') {//如果是语音类型
return $this->sendVoice($content, $msgSend['id']);
} elseif (isset($msgSend['type']) && $msgSend['type'] == 'video') {//如果是视频类型
return $this->sendVideo($content, $msgSend);
} else {
return $this->sendText($content, $msgSend);
}
}
/**
* Des:发送文字
* Name: sendText
* @param $content
* @param $msgSend
* @return string
* @author 倪宗锋
*/
private function sendText($content, $msgSend)
{
$textTpl = '' . "
%s
";
$msgType = "text";
if (is_array($msgSend)) {
$msgSend = $msgSend['text'];
}
$resultStr = sprintf($textTpl, $content['FromUserName'], $content['ToUserName'], time(), $msgType, $msgSend);
return $resultStr;
}
/**
* Des:发送图文
* Name: sendNews
* @param $content array
* @param $mediaId string 素材图文 ID
* @return string
* @author 倪宗锋
*/
private function sendNews($content, $mediaId)
{
$news = $this->getNewsByMediaId($mediaId);
return $this->transmitNews($content, $news);
}
/**
* Des:发送图片
* Name: sendImage
* @param $content
* @param $mediaId
* @return string
* @author 倪宗锋
*/
private function sendImage($content, $mediaId)
{
$xmlTpl = '' . "
%s
";
$result = sprintf($xmlTpl, $content['FromUserName'], $content['ToUserName'], time(), $mediaId);
return $result;
}
/**
* Des:发送语音
* Name: sendVoice
* @param $content
* @param $mediaId
* @return string
* @author 倪宗锋
*/
private function sendVoice($content, $mediaId)
{
$xmlTpl = '' . "
%s
";
$result = sprintf($xmlTpl, $content['FromUserName'], $content['ToUserName'], time(), $mediaId);
return $result;
}
/**
* Des:发送视频
* Name: sendVideo
* @param $content
* @param $sendMsg
* @return string
* @author 倪宗锋
*/
private function sendVideo($content, $sendMsg)
{
$xmlTpl = '' . "
%s
";
$result = sprintf($xmlTpl, $content['FromUserName'], $content['ToUserName'], time(), $sendMsg['id'], $sendMsg["title"], $sendMsg["des"]);
return $result;
}
/**
* Des:根据ID获取图文信息
* Name: getNewsByMediaId
* @param $data_media_id
* @return array
* @author 倪宗锋
*/
public function getNewsByMediaId($data_media_id)
{
$data_media_id = '{"media_id":"' . $data_media_id . '"}';
$url = "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=" . $this->getAccessToken();
$response = $this->_requestPost($url, $data_media_id);
$media = json_decode($response, true);
$mediaArray = $media['news_item'];
$content = array();
foreach ($mediaArray as $k => $v) {
if ($k == 0 || $k == 1)
$content[] = array("Title" => $v['title'], "Description" => $v['digest'], "PicUrl" => $v['thumb_url'], "Url" => $v['url']);
elseif ($k == 2) {
$content[] = array("Title" => $v['title'], "Description" => $v['digest'], "PicUrl" => $v['thumb_url'], "Url" => $v['content_source_url']);
} else
$content[] = array("Title" => $v['title'], "Description" => $v['digest'], "PicUrl" => $v['thumb_url'], "Url" => $v['content_source_url']);
}
return $content;
}
/**
* Des:图文推送数据处理
* Name: transmitNews
* @param $content
* @param $newsArray
* @return string
* @author 倪宗锋
*/
private function transmitNews($content, $newsArray)
{
if (!is_array($newsArray)) {
return '';
}
$itemTpl = '' . "-
";
$item_str = "";
foreach ($newsArray as $item) {
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
}
$xmlTpl = '' . "
" . time() . "
" . count($newsArray) . "
$item_str
";
return $xmlTpl;
}
/*************************=========第一次请求校验==========***********************************/
/**
* Des:第一次校验
* Name: valid
* @return bool
* @author 倪宗锋
*/
public function valid()
{
$echoStr = $_GET["echostr"];
if ($this->checkSignature()) {
$this->response = $echoStr;
}
return $this->response;
}
/***********************************通用函数*******************************************************/
/**
* Des:根据openid获取用户信息
* Name: getUserInfoByOpenid
* @param $openid
* @return array
* @author 倪宗锋
*/
public static function getUserInfoByOpenid($openid)
{
$token = static::getAccessToken();
$userInfo = static::getWeChatInfo($openid, $token);
return $userInfo;
}
/**
* Des:通用获取微信用户信息
* Name: getWeChatInfo
* @param $openid
* @param $accessToken string 基础公共access_token
* @return array
* @author 倪宗锋
*/
public static function getWeChatInfo($openid, $accessToken)
{
$query = array(
'access_token' => $accessToken,
'openid' => $openid,
'lang' => 'zh_CN'
);
$url = "https://api.weixin.qq.com/cgi-bin/user/info?";
$url .= http_build_query($query);
$curl = new CurlInterface('', 4);
$arr = $curl->execute($url);
$return = [
'nickname' => $arr['nickname'],
'headimgurl' => $arr['headimgurl'],
'sex' => $arr['sex'],
'country' => $arr['country'],
'city' => $arr['city'],
'province' => $arr['province']
];
return $return;
}
/**
* Des:授权登录获取用户信息
* Name: getAuthWeChatInfo
* @param $openid
* @param $accessToken string 授权获取的accessToken
* @return array
* @author 倪宗锋
*/
public static function getAuthWeChatInfo($openid, $accessToken)
{
$query = array(
'access_token' => $accessToken,
'openid' => $openid,
'lang' => 'zh_CN'
);
$url = "https://api.weixin.qq.com/sns/userinfo?";
$url .= http_build_query($query);
$curl = new CurlInterface('', 4);
$arr = $curl->execute($url);
$return = [
'nickname' => $arr['nickname'],
'headimgurl' => $arr['headimgurl'],
'sex' => $arr['sex'],
'country' => $arr['country'],
'city' => $arr['city'],
'province' => $arr['province']
];
return $return;
}
/**
* Des:数据校验
* Name: checkSignature
* @return bool
* @author 倪宗锋
*/
private function checkSignature()
{
$token = $this->token;
$signature = isset($_GET["signature"]) ? $_GET["signature"] : "";
$timestamp = isset($_GET["timestamp"]) ? $_GET["timestamp"] : "";
$nonce = isset($_GET["nonce"]) ? $_GET["nonce"] : "";
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
return true;
} else {
return false;
}
}
/**
* Des:参数解析
* Name: getContent
* @author 倪宗锋
*/
private function getContent()
{
$content = file_get_contents("php://input");
libxml_disable_entity_loader(true);
$this->request = (array)simplexml_load_string($content, 'SimpleXMLElement', LIBXML_NOCDATA);
return $this->request;
}
/**
* Des:获取token
* Name: getAccessToken
* @param $appid
* @return string
* @author 倪宗锋
*/
public static function getAccessToken($appid = '')
{
$wxConfig = Util::getWeChatConfig($appid);
$appid = $wxConfig['appid'];
$appsecret = $wxConfig['appsecret'];
$access_token = static::getWxAccessToken($appid, $appsecret);
return $access_token;
}
/**
* Des:获取指定的微信公众号的token
* Name: getWxAccessToken
* @param $appid
* @param $appsecret
* @return mixed|string
* @author 倪宗锋
*/
public static function getWxAccessToken($appid, $appsecret)
{
$key = $appid . 'access_token';
$memcache = \Yii::$app->getCache();
$access_token = $memcache->get($key);
if (empty($access_token)) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
$getToken = self::_requestGet($url);//发起get请求获取token
$res = json_decode($getToken, true);//json转换成数组
if (empty($res['access_token'])) {
return '';
}
$access_token = $res['access_token'];
$memcache->set($key, $access_token, 3600);
}
return $access_token;
}
/**
* Function Description:根据code获取token
* Function Name: getToken
* @param $code
*
* @return array
*
* @author 倪宗锋
*/
public static function getToken($code)
{
$WxPayConfig = Util::getWeChatConfig();
$siteConfig = Util::getSiteConfig();
$urlObj["appid"] = $WxPayConfig['appid'];
$urlObj["secret"] = $WxPayConfig['appsecret'];
$urlObj["code"] = $code;
$urlObj["grant_type"] = "authorization_code";
$bizString = http_build_query($urlObj);
$url = $siteConfig['authTokenUrl'] . $bizString;
$curlInterface = new CurlInterface('', 4);
$curlInterface->setBaseUrl($url);
$getToken = $curlInterface->execute('', 'GET');
if (empty($getToken['openid'])) {
return Util::returnArrEr('参数无效!');
}
return Util::returnArrSu('', $getToken);
}
/**
* Des:发起get请求
* Name: _requestGet
* @param $url string
* @param bool|true $ssl
* @return bool|mixed
* @author 倪宗锋
*/
public static function _requestGet($url, $ssl = true)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
if ($ssl) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
}
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
if ($response === false) {
return false;
}
return $response;
}
/**
* Des:发起post请求
* Name: _requestPost
* @param $url
* @param $data
* @param bool|true $ssl
* @return bool|mixed
* @author 倪宗锋
*/
public static function _requestPost($url, $data, $ssl = true)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
if ($ssl) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
}
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
if ($response === false) {
return false;
}
return $response;
}
/**
* Des:获取
* Name: httpRequest
* @param $url
* @param null $data
* @return mixed
* @author 倪宗锋
*/
static function httpRequest($url, $data = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
/**
* 分销用户二维码
*/
public static function getFxQrCode($fx_uid)
{
$config = Util::getSiteConfig();
$imgUrl = ROOT_PATH . '/web/fx/images/FxQrCode/' . $fx_uid . '.png';
$showUrl = $config['host_name'] . '/web/fx/images/FxQrCode/' . $fx_uid . '.png';
if (file_exists($imgUrl)) {
return Util::returnArrSu('', array('url' => $showUrl));
}
$logo = ROOT_PATH . '/web/fx/images/logo.png';
$qRCode = $config['host_name'] . '/shop/?r=weChat/we-chat/q-r-code-home&id=' . $fx_uid;
$addFlag = Util::addQRCode($qRCode, $imgUrl, 1, true, false, $logo);
if ($addFlag['flag'] == false) {
return Util::returnArrEr('生成二维码失败!');
}
return Util::returnArrSu('', array('url' => $showUrl));
}
public static function getSignPackage($url)
{
$jsapiTicket = static::getJsApiTicket();
// 注意 URL 一定要动态获取,不能 hardcode.
// $url = "http://nwx.zhizhuchuxing.cn/web/shop/test.html";
$timestamp = time();
$nonceStr = WeChatPay::getNonceStr(16);
// 这里参数的顺序要按照 key 值 ASCII 码升序排序
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
$signature = sha1($string);
$config = Util::getWeChatConfig();
$signPackage = array(
"appId" => $config['appid'],
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string
);
return $signPackage;
}
public static function getJsApiTicket()
{
// jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
$cache = \Yii::$app->cache;
$data = $cache->get('jsapiticket');
if (empty($data['expire_time']) || $data['expire_time'] < time()) {
$accessToken = static::getAccessToken();
// 如果是企业号用以下 URL 获取 ticket
// $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
$curl = new CurlInterface('', 5);
$res = json_decode($curl->execute($url), true);
$ticket = $res['ticket'];
if ($ticket) {
$data = [];
$data['expire_time'] = time() + 7000;
$data['jsapi_ticket'] = $ticket;
$cache->set('jsapiticket', $data);
}
} else {
$ticket = $data['jsapi_ticket'];
}
return $ticket;
}
/**
* 发送自定义的模板消息
* @param $toUser
* @param $template
* @param $url
* @param $data
* @param $appid string 默认当前系统的微信配置 ,可更换为 其他微信公众号的配置
* @param string $topColor
* @return bool
*/
public static function sendWxTemplate($toUser, $template, $url, $data, $topColor = '#7B68EE', $appid = '')
{
if ($appid != '') {
Util::setSiteConfig('entryAuthWeChat', $appid);//变更微信公众号配置
}
$wxConfig = Util::getWeChatConfig();
$template_config = require ROOT_PATH.'/common/config/wechatConfig/wxInterface/'.$wxConfig['mch_id'].'/Wx.msg.template.config.php';
if (empty($template_config[$template])){
return false;
}
$template = array(
'touser' => $toUser,
'template_id' => $template_config[$template],
'url' => $url,
'topcolor' => $topColor,
'data' => $data
);
$token = static::getAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $token;
$curl = new CurlInterface($template, 1);
$dataRes = $curl->execute($url, 'post');
if ($dataRes['errcode'] == 0) {
return true;
} else {
return false;
}
}
}