<?php
namespace WeOpen;
use WeChat\Contracts\DataArray;
use WeChat\Contracts\Tools;
use WeChat\Exceptions\InvalidArgumentException;
use WeChat\Exceptions\InvalidResponseException;
use WeChat\Receive;
class Service
{
protected $config;
public function __construct(array $options)
{
if (empty($options['component_token'])) {
throw new InvalidArgumentException("Missing Config -- [component_token]");
}
if (empty($options['component_appid'])) {
throw new InvalidArgumentException("Missing Config -- [component_appid]");
}
if (empty($options['component_appsecret'])) {
throw new InvalidArgumentException("Missing Config -- [component_appsecret]");
}
if (empty($options['component_encodingaeskey'])) {
throw new InvalidArgumentException("Missing Config -- [component_encodingaeskey]");
}
if (!empty($options['cache_path'])) {
Tools::$cache_path = $options['cache_path'];
}
$this->config = new DataArray($options);
}
public function getComonentTicket()
{
$receive = new Receive([
'token' => $this->config->get('component_token'),
'appid' => $this->config->get('component_appid'),
'appsecret' => $this->config->get('component_appsecret'),
'encodingaeskey' => $this->config->get('component_encodingaeskey'),
'cache_path' => $this->config->get('cache_path'),
]);
$data = $receive->getReceive();
if (!empty($data['ComponentVerifyTicket'])) {
Tools::setCache('component_verify_ticket', $data['ComponentVerifyTicket']);
}
return $data;
}
public function getComponentAccessToken()
{
$cache = 'wechat_component_access_token';
if (($component_access_token = Tools::getCache($cache))) {
return $component_access_token;
}
$data = [
'component_appid' => $this->config->get('component_appid'),
'component_appsecret' => $this->config->get('component_appsecret'),
'component_verify_ticket' => Tools::getCache('component_verify_ticket'),
];
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
$result = $this->httpPostForJson($url, $data);
if (empty($result['component_access_token'])) {
throw new InvalidResponseException($result['errmsg'], $result['errcode'], $data);
}
Tools::setCache($cache, $result['component_access_token'], 7000);
return $result['component_access_token'];
}
public function getAuthorizerInfo($authorizer_appid)
{
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token={$component_access_token}";
$data = [
'authorizer_appid' => $authorizer_appid,
'component_appid' => $this->config->get('component_appid'),
];
$result = $this->httpPostForJson($url, $data);
if (empty($result['authorizer_info'])) {
throw new InvalidResponseException($result['errmsg'], $result['errcode'], $data);
}
return $result['authorizer_info'];
}
public function setAuthorizerOption($authorizer_appid, $option_name, $option_value)
{
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/component/ api_set_authorizer_option?component_access_token={$component_access_token}";
$result = $this->httpPostForJson($url, [
'option_name' => $option_name,
'option_value' => $option_value,
'authorizer_appid' => $authorizer_appid,
'component_appid' => $this->config->get('component_appid'),
]);
return $result;
}
public function getPreauthCode()
{
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={$component_access_token}";
$result = $this->httpPostForJson($url, ['component_appid' => $this->config->get('component_appid')]);
if (empty($result['pre_auth_code'])) {
throw new InvalidResponseException('GetPreauthCode Faild.', '0', $result);
}
return $result['pre_auth_code'];
}
public function getAuthRedirect($redirect_uri, $auth_type = 3)
{
$redirect_uri = urlencode($redirect_uri);
$pre_auth_code = $this->getPreauthCode();
$component_appid = $this->config->get('component_appid');
return "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={$component_appid}&pre_auth_code={$pre_auth_code}&redirect_uri={$redirect_uri}&auth_type={$auth_type}";
}
public function getQueryAuthorizerInfo($auth_code = null)
{
if (is_null($auth_code) && isset($_GET['auth_code'])) {
$auth_code = $_GET['auth_code'];
}
if (empty($auth_code)) {
return false;
}
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={$component_access_token}";
$data = [
'component_appid' => $this->config->get('component_appid'),
'authorization_code' => $auth_code,
];
$result = $this->httpPostForJson($url, $data);
if (empty($result['authorization_info'])) {
throw new InvalidResponseException($result['errmsg'], $result['errcode'], $data);
}
$authorizer_appid = $result['authorization_info']['authorizer_appid'];
$authorizer_access_token = $result['authorization_info']['authorizer_access_token'];
Tools::setCache("{$authorizer_appid}_access_token", $authorizer_access_token, 7000);
return $result['authorization_info'];
}
public function refreshAccessToken($authorizer_appid, $authorizer_refresh_token)
{
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token={$component_access_token}";
$data = [
'authorizer_appid' => $authorizer_appid,
'authorizer_refresh_token' => $authorizer_refresh_token,
'component_appid' => $this->config->get('component_appid'),
];
$result = $this->httpPostForJson($url, $data);
if (empty($result['authorizer_access_token'])) {
throw new InvalidResponseException($result['errmsg'], $result['errcode'], $data);
}
Tools::setCache("{$authorizer_appid}_access_token", $result['authorizer_access_token'], 7000);
return $result;
}
public function getOauthRedirect($authorizer_appid, $redirect_uri, $scope = 'snsapi_userinfo')
{
$redirect_url = urlencode($redirect_uri);
$component_appid = $this->config->get('component_appid');
return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$authorizer_appid}&redirect_uri={$redirect_url}&response_type=code&scope={$scope}&state={$authorizer_appid}&component_appid={$component_appid}#wechat_redirect";
}
public function getOauthAccessToken($authorizer_appid)
{
if (empty($_GET['code'])) {
return false;
}
$component_appid = $this->config->get('component_appid');
$component_access_token = $this->getComponentAccessToken();
$url = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid={$authorizer_appid}&code={$_GET['code']}&grant_type=authorization_code&component_appid={$component_appid}&component_access_token={$component_access_token}";
$result = $this->httpGetForJson($url);
return $result !== false ? $result : false;
}
public function instance($type, $authorizer_appid)
{
$className = 'WeChat\\' . ucfirst(strtolower($type));
return new $className($this->getConfig($authorizer_appid));
}
public function getConfig($authorizer_appid)
{
$config = $this->config->get();
$config['appid'] = $authorizer_appid;
$config['token'] = $this->config->get('component_token');
$config['appsecret'] = $this->config->get('component_appsecret');
$config['encodingaeskey'] = $this->config->get('component_encodingaeskey');
return $config;
}
protected function httpPostForJson($url, array $data, $buildToJson = true)
{
return json_decode(Tools::post($url, $buildToJson ? Tools::arr2json($data) : $data), true);
}
protected function httpGetForJson($url)
{
return json_decode(Tools::get($url), true);
}
}