config = Dever::config('wechat')->cAll; if (!$project) { $appid = Dever::input('appid'); if ($appid) { $project = Dever::db('main/project')->one(array('option_type' => $type, 'option_appid' => $appid)); } if (!$project) { $project = Dever::input('project', 1); } } if (!$project) { Dever::alert('project is not exits!'); } if (is_numeric($project)) { $project = Dever::db('main/project')->one($project); } $this->project = $project; } /** * 获取当前站点的配置 * * @return mixed */ public function project() { return $this->project; } /** * 获取当前基本的配置 * * @return mixed */ public function config() { return $this->config; } /** * 更新数据库 * * @return mixed */ private function save($type = 'ticket', $value, $expires = false, $interval = 2000) { if (strpos($type, '.')) { $temp = explode('.', $type); $table = 'main/' . $temp[1]; } else { $table = 'main/' . $type; } $db = Dever::db($table); $where['option_project_id'] = $this->project['id']; $info = $db->one($where); $update = false; if ($info && time() - $info['mdate'] >= $info['expires']) { $update = true; } elseif($info) { return $info['value']; } if (!$info) { $update = false; } if (!$value) { $value = $this->param($type); } $data = array(); if (is_array($value) || (is_string($value) && strstr($value, 'http://'))) { $result = $this->curl(false, $value); $key = $type; if ($type == 'token') { $key = 'access_token'; } if ($result && isset($result[$key])) { $data = $result; $data['value'] = $result[$key]; $data['expires'] = $result['expires_in']; } } else { $data['value'] = $value; $data['expires'] = $expires; } if ($data && isset($data['value']) && $data['value']) { $data['project_id'] = $this->project['id']; $expires = $data['expires'] - $interval; if ($expires <= 0) { $data['expires'] = $data['expires'] - 300; } else { $data['expires'] = $expires; } if ($update == true) { $data['where_id'] = $info['id']; $db->update($data); } else { $db->insert($data); } } elseif($info && $info['value']) { $data['value'] = $info['value']; } return $data['value']; } /** * 获取最新的token * * @return mixed */ public function token($value = false, $expires = false, $interval = 2000) { return $this->save('token', $value, $expires, $interval); } /** * 获取最新的ticket * * @return mixed */ public function ticket($value = false, $expires = false, $interval = 200) { return $this->save('ticket', $value, $expires, $interval); } /** * 获取最新的oauth token * * @return mixed */ public function oauth($value = false, $expires = false, $interval = 200) { return $this->save('oauth.oauth', $value, $expires, $interval); } /** * 获取最新的code * * @return mixed */ public function code($value = false, $expires = false, $interval = 200) { return $this->save('oauth.code', $value, $expires, $interval); } /** * 获取最新的oauth login地址 * * @return mixed */ public function login($callback = false, $code = false, $location = true) { if (!$code) { $code = $this->code(); } $callback = urlencode(Dever::url($callback)); $config = $this->param('oauth.login', array('code' => $code, 'redirect' => $callback)); $url = $config['url'] . http_build_query($config['param']); if ($location == true) { Dever::location($url); } return $url; } /** * 从wechat获取数据 * * @return mixed */ public function curl($method, $param = array()) { if (is_string($param)) { $result = json_decode(Dever::curl($param), true); } else { if ($method) { $param = $this->param($method, $param); } $result = json_decode(Dever::curl($param['url'], $param['param'], $param['method'], $param['json']), true); } if (isset($result['errcode']) && $result['errcode'] != 0) { $result = $param + $result; Dever::log($result); Dever::alert(json_encode($result)); } if (isset($param['response'])) { foreach ($param['response'] as $k => $v) { if (strpos($k, '.')) { $temp = explode('.', $k); if (isset($result[$temp[0]][$temp[1]])) { $result[$v] = $result[$temp[0]][$temp[1]]; } } elseif (isset($result[$k])) { $result[$v] = $result[$k]; } } } return $result; } /** * 拼装wechat需要的参数 * * @return mixed */ public function param($method, $param = array()) { if (strpos($method, '.')) { $temp = explode('.', $method); $config = $this->config[$temp[0]][$temp[1]]; } else { if (!isset($this->config[$method])) { return false; } $config = $this->config[$method]; } $param = $this->project + $param; foreach ($config['param'] as $k => $v) { if ($v == 'token') { $config['url'] .= $k . '=' . $this->token(); unset($config['param'][$k]); } elseif ($v == 'ticket') { $config['param'][$k] = $this->ticket(); } elseif ($v == 'code') { $config['param'][$k] = $this->code(); }elseif ($v == 'oauth') { $config['param'][$k] = $this->oauth(); } elseif (isset($param[$v]) && $param[$v]) { $config['param'][$k] = $param[$v]; } elseif($v) { $config['param'][$k] = $v; } } $config['json'] = isset($config['json']) && $config['json'] ? true : false; return $config; } /** * 消息解密 * * @return mixed */ public function decode($sign, $timestamp, $nonce, $encrypt) { include(DEVER_PROJECT_PATH . 'example/wxBizMsgCrypt.php'); $crypt = new \WXBizMsgCrypt($this->project['token'], $this->project['key'], $this->project['appid']); $format = ""; $xml = sprintf($format, $encrypt); $result = ''; $code = $crypt->decryptMsg($sign, $timestamp, $nonce, $xml, $result); if ($code == 0) { libxml_disable_entity_loader(true); $result = (array) simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA); } return $result; } /** * 获取nonce * * @return mixed */ public function nonce() { return substr(md5(microtime()), rand(10, 15)); } /** * 获取signature * * @return mixed */ public function signature($ticket, $url, $timestamp, $noncestr) { $info = array(); $info['jsapi_ticket'] = $ticket; $info['url'] = $url; $info['timestamp'] = $timestamp; $info['noncestr'] = $noncestr; ksort($info); $signature_string = substr(http_build_query($info), 0, -1); return sha1($signature_string); } }