From 382cddf85f5ce40e0f8112dbab8dbc44edbaeec6 Mon Sep 17 00:00:00 2001 From: Martin Zhou <1009465756@qq.com> Date: Tue, 7 Feb 2017 18:10:55 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=A8Extend=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Application/Extend/Oauth/ThinkOauth.class.php | 261 ++++++++++++++++++ Application/Extend/Page.class.php | 145 ++++++++++ 2 files changed, 406 insertions(+) create mode 100644 Application/Extend/Oauth/ThinkOauth.class.php create mode 100644 Application/Extend/Page.class.php diff --git a/Application/Extend/Oauth/ThinkOauth.class.php b/Application/Extend/Oauth/ThinkOauth.class.php new file mode 100644 index 0000000..45d81af --- /dev/null +++ b/Application/Extend/Oauth/ThinkOauth.class.php @@ -0,0 +1,261 @@ + +// +---------------------------------------------------------------------- +// | ThinkOauth.class.php 2013-02-25 +// +---------------------------------------------------------------------- +namespace Extend\Oauth; + +abstract class ThinkOauth{ + /** + * oauth版本 + * @var string + */ + protected $Version = '2.0'; + + /** + * 申请应用时分配的app_key + * @var string + */ + protected $AppKey = ''; + + /** + * 申请应用时分配的 app_secret + * @var string + */ + protected $AppSecret = ''; + + /** + * 授权类型 response_type 目前只能为code + * @var string + */ + protected $ResponseType = 'code'; + + /** + * grant_type 目前只能为 authorization_code + * @var string + */ + protected $GrantType = 'authorization_code'; + + /** + * 回调页面URL 可以通过配置文件配置 + * @var string + */ + protected $Callback = ''; + + /** + * 获取request_code的额外参数 URL查询字符串格式 + * @var srting + */ + protected $Authorize = ''; + + /** + * 获取request_code请求的URL + * @var string + */ + protected $GetRequestCodeURL = ''; + + /** + * 获取access_token请求的URL + * @var string + */ + protected $GetAccessTokenURL = ''; + + /** + * API根路径 + * @var string + */ + protected $ApiBase = ''; + + /** + * 授权后获取到的TOKEN信息 + * @var array + */ + protected $Token = null; + + /** + * 调用接口类型 + * @var string + */ + private $Type = ''; + + /** + * 构造方法,配置应用信息 + * @param array $token + */ + public function __construct($token = null){ + //设置SDK类型 + $class = get_class($this); + $this->Type = strtoupper(substr($class, 0, strlen($class)-3)); + + //获取应用配置 + $config = C("THINK_SDK_{$this->Type}"); + + if(empty($config['APP_KEY']) || empty($config['APP_SECRET'])){ + throw new Exception('请配置您申请的APP_KEY和APP_SECRET'); + } else { + $this->AppKey = $config['APP_KEY']; + $this->AppSecret = $config['APP_SECRET']; + $this->Token = $token; //设置获取到的TOKEN + } + } + + /** + * 取得Oauth实例 + * @static + * @return mixed 返回Oauth + */ + public static function getInstance($type, $token = null) { + $name = ucfirst(strtolower($type)) . 'SDK'; + require_once "sdk/{$name}.class.php"; + if (class_exists($name)) { + return new $name($token); + } else { + halt(L('_CLASS_NOT_EXIST_') . ':' . $name); + } + } + + /** + * 初始化配置 + */ + private function config(){ + $config = C("THINK_SDK_{$this->Type}"); + if(!empty($config['AUTHORIZE'])) + $this->Authorize = $config['AUTHORIZE']; + if(!empty($config['CALLBACK'])) + $this->Callback = $config['CALLBACK']; + else + throw new Exception('请配置回调页面地址'); + } + + /** + * 请求code + */ + public function getRequestCodeURL(){ + $this->config(); + //Oauth 标准参数 + $params = array( + 'client_id' => $this->AppKey, + 'redirect_uri' => $this->Callback, + 'response_type' => $this->ResponseType, + ); + + //获取额外参数 + if($this->Authorize){ + parse_str($this->Authorize, $_param); + if(is_array($_param)){ + $params = array_merge($params, $_param); + } else { + throw new Exception('AUTHORIZE配置不正确!'); + } + } + return $this->GetRequestCodeURL . '?' . http_build_query($params); + } + + /** + * 获取access_token + * @param string $code 上一步请求到的code + */ + public function getAccessToken($code, $extend = null){ + $this->config(); + $params = array( + 'client_id' => $this->AppKey, + 'client_secret' => $this->AppSecret, + 'grant_type' => $this->GrantType, + 'code' => $code, + 'redirect_uri' => $this->Callback, + ); + + $data = $this->http($this->GetAccessTokenURL, $params, 'POST'); + $this->Token = $this->parseToken($data, $extend); + return $this->Token; + } + + /** + * 合并默认参数和额外参数 + * @param array $params 默认参数 + * @param array/string $param 额外参数 + * @return array: + */ + protected function param($params, $param){ + if(is_string($param)) + parse_str($param, $param); + return array_merge($params, $param); + } + + /** + * 获取指定API请求的URL + * @param string $api API名称 + * @param string $fix api后缀 + * @return string 请求的完整URL + */ + protected function url($api, $fix = ''){ + return $this->ApiBase . $api . $fix; + } + + /** + * 发送HTTP请求方法,目前只支持CURL发送请求 + * @param string $url 请求URL + * @param array $params 请求参数 + * @param string $method 请求方法GET/POST + * @return array $data 响应数据 + */ + protected function http($url, $params, $method = 'GET', $header = array(), $multi = false){ + $opts = array( + CURLOPT_TIMEOUT => 30, + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_HTTPHEADER => $header + ); + + /* 根据请求类型设置特定参数 */ + switch(strtoupper($method)){ + case 'GET': + $opts[CURLOPT_URL] = $url . '?' . http_build_query($params); + break; + case 'POST': + //判断是否传输文件 + $params = $multi ? $params : http_build_query($params); + $opts[CURLOPT_URL] = $url; + $opts[CURLOPT_POST] = 1; + $opts[CURLOPT_POSTFIELDS] = $params; + break; + default: + throw new Exception('不支持的请求方式!'); + } + + /* 初始化并执行curl请求 */ + $ch = curl_init(); + curl_setopt_array($ch, $opts); + $data = curl_exec($ch); + $error = curl_error($ch); + curl_close($ch); + if($error) throw new Exception('请求发生错误:' . $error); + return $data; + } + + /** + * 抽象方法,在SNSSDK中实现 + * 组装接口调用参数 并调用接口 + */ + abstract protected function call($api, $param = '', $method = 'GET', $multi = false); + + /** + * 抽象方法,在SNSSDK中实现 + * 解析access_token方法请求后的返回值 + */ + abstract protected function parseToken($result, $extend); + + /** + * 抽象方法,在SNSSDK中实现 + * 获取当前授权用户的SNS标识 + */ + abstract public function openid(); +} \ No newline at end of file diff --git a/Application/Extend/Page.class.php b/Application/Extend/Page.class.php new file mode 100644 index 0000000..fc7aa71 --- /dev/null +++ b/Application/Extend/Page.class.php @@ -0,0 +1,145 @@ + +// +---------------------------------------------------------------------- +namespace Extend; + +class Page{ + public $firstRow; // 起始行数 + public $listRows; // 列表每页显示行数 + public $parameter; // 分页跳转时要带的参数 + public $totalRows; // 总行数 + public $totalPages; // 分页总页面数 + public $rollPage = 11;// 分页栏每页显示的页数 + public $lastSuffix = true; // 最后一页是否显示总页数 + + private $p = 'p'; //分页参数名 + private $url = ''; //当前链接URL + private $nowPage = 1; + + // 分页显示定制 + private $config = array( + 'header' => '共 %TOTAL_ROW% 条记录', + 'prev' => '<<', + 'next' => '>>', + 'first' => '1...', + 'last' => '...%TOTAL_PAGE%', + 'theme' => '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%', + ); + + /** + * 架构函数 + * @param array $totalRows 总的记录数 + * @param array $listRows 每页显示记录数 + * @param array $parameter 分页跳转的参数 + */ + public function __construct($totalRows, $listRows=20, $parameter = array()) { + C('VAR_PAGE') && $this->p = C('VAR_PAGE'); //设置分页参数名称 + /* 基础设置 */ + $this->totalRows = $totalRows; //设置总记录数 + $this->listRows = $listRows; //设置每页显示行数 + $this->parameter = empty($parameter) ? $_GET : $parameter; + $this->nowPage = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]); + $this->nowPage = $this->nowPage>0 ? $this->nowPage : 1; + $this->firstRow = $this->listRows * ($this->nowPage - 1); + } + + /** + * 定制分页链接设置 + * @param string $name 设置名称 + * @param string $value 设置值 + */ + public function setConfig($name,$value) { + if(isset($this->config[$name])) { + $this->config[$name] = $value; + } + } + + /** + * 生成链接URL + * @param integer $page 页码 + * @return string + */ + private function url($page){ + return str_replace(urlencode('[PAGE]'), $page, $this->url); + } + + /** + * 组装分页链接 + * @return string + */ + public function show() { + if(0 == $this->totalRows) return ''; + + /* 生成URL */ + $this->parameter[$this->p] = '[PAGE]'; + $this->url = U(ACTION_NAME, $this->parameter); + /* 计算分页信息 */ + $this->totalPages = ceil($this->totalRows / $this->listRows); //总页数 + if(!empty($this->totalPages) && $this->nowPage > $this->totalPages) { + $this->nowPage = $this->totalPages; + } + + /* 计算分页临时变量 */ + $now_cool_page = $this->rollPage/2; + $now_cool_page_ceil = ceil($now_cool_page); + $this->lastSuffix && $this->config['last'] = $this->totalPages; + + //上一页 + $up_row = $this->nowPage - 1; + $up_page = $up_row > 0 ? '
  • ' : ''; + + //下一页 + $down_row = $this->nowPage + 1; + $down_page = ($down_row <= $this->totalPages) ? '
  • ' : ''; + + //第一页 + $the_first = ''; + if($this->totalPages > $this->rollPage && ($this->nowPage - $now_cool_page) >= 1){ + $the_first = '
  • ' . $this->config['first'] . '
  • '; + } + + //最后一页 + $the_end = ''; + if($this->totalPages > $this->rollPage && ($this->nowPage + $now_cool_page) < $this->totalPages){ + $the_end = '
  • ' . $this->config['last'] . '
  • '; + } + + //数字连接 + $link_page = ""; + for($i = 1; $i <= $this->rollPage; $i++){ + if(($this->nowPage - $now_cool_page) <= 0 ){ + $page = $i; + }elseif(($this->nowPage + $now_cool_page - 1) >= $this->totalPages){ + $page = $this->totalPages - $this->rollPage + $i; + }else{ + $page = $this->nowPage - $now_cool_page_ceil + $i; + } + if($page > 0 && $page != $this->nowPage){ + + if($page <= $this->totalPages){ + $link_page .= '
  • ' . $page . '
  • '; + }else{ + break; + } + }else{ + if($page > 0 && $this->totalPages != 1){ + $link_page .= '
  • ' . $page . '
  • '; + } + } + } + + //替换分页内容 + $page_str = str_replace( + array('%HEADER%', '%NOW_PAGE%', '%UP_PAGE%', '%DOWN_PAGE%', '%FIRST%', '%LINK_PAGE%', '%END%', '%TOTAL_ROW%', '%TOTAL_PAGE%'), + array($this->config['header'], $this->nowPage, $up_page, $down_page, $the_first, $link_page, $the_end, $this->totalRows, $this->totalPages), + $this->config['theme']); + return "
      {$page_str}
    "; + } +}