Skip to content
Browse files

version1.0

  • Loading branch information...
0 parents commit b94e601e23e3f0d03186c38a2ff3af3af1049d44 ganxun committed
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
163 .gitignore
@@ -0,0 +1,163 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+*.dotCover
+
+## TODO: If you have NuGet Package Restore enabled, uncomment this
+#packages/
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+*.Cache
+ClientBin
+stylecop.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
+
+
+############
+## Windows
+############
+
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist
+build
+eggs
+parts
+bin
+var
+sdist
+develop-eggs
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+
+# Mac crap
+.DS_Store
944 Baidu.php
@@ -0,0 +1,944 @@
+<?php
+/***************************************************************************
+ *
+ * Copyright (c) 2011 Baidu.com, Inc. All Rights Reserved
+ *
+ **************************************************************************/
+
+/**
+ * Baidu.php
+ *
+ *
+ * @package Baidu
+ * @author wulin02(wulin02@baidu.com)
+ * @version $Revision: 1.0 Mon Jun 27 10:52:18 CST 2011
+ **/
+
+// In PHP 5.2 or higher we don't need to bring this in
+if (!function_exists('json_encode')) {
+
+ require_once(dirname(__FILE__) . '/JSON.php');
+
+ function json_encode($value)
+ {
+ $services_json = new Services_JSON();
+ return $services_json->encode($value);
+ }
+
+ function json_decode($json, $assoc = false)
+ {
+ $services_json = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0);
+ return $services_json->decode($json);
+ }
+}
+
+require_once(dirname(__FILE__) . '/BaiduStore.php');
+
+// when using bae(baidu app engine) to deploy the application,
+// just uncomment the following two lines.
+//require_once('app_config.php');
+//require_once(BAE_API_PATH . '/BaeFetchUrl.class.php');
+
+class Baidu
+{
+ /**
+ * URL prefix definition of Baidu OpenAPI interfaces.
+ */
+ public static $BD_OPENAPI_URL_PREFIXS = array(
+ 'public' => 'http://openapi.baidu.com/public/2.0/',
+ 'https' => 'https://openapi.baidu.com/rest/2.0/',
+ 'http' => 'http://openapi.baidu.com/rest/2.0/',
+ );
+
+ /**
+ * Endpoints definition of Baidu OAuth2.0.
+ */
+ public static $BD_OAUTH2_ENDPOINTS = array(
+ 'authorize' => 'https://openapi.baidu.com/oauth/2.0/authorize',
+ 'token' => 'https://openapi.baidu.com/oauth/2.0/token',
+ 'logout' => 'https://openapi.baidu.com/connect/2.0/logout',
+ );
+
+ /**
+ * List of query parameters that get automatically dropped when rebuilding
+ * the current URL.
+ */
+ protected static $DROP_QUERY_PARAMS = array(
+ 'code',
+ 'state',
+ );
+
+ /**
+ * Default options for curl.
+ */
+ protected $curlOpts = array(
+ CURLOPT_CONNECTTIMEOUT => 3,
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_USERAGENT => 'baidu-restclient-php-2.0',
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HEADER => false,
+ CURLOPT_FOLLOWLOCATION => false,
+ );
+
+ protected $apiKey;
+ protected $apiSecret;
+
+ /**
+ * @var BaiduStore
+ */
+ protected $store = null;
+
+ protected $state = null;
+
+ /**
+ * @var array
+ */
+ protected $session = null;
+
+ protected $format = 'json';
+ protected $httpMethod = 'GET';
+ protected $useHttps = false;
+ protected $finalEncode = 'UTF-8';
+
+ protected $errcode = 0;
+ protected $errmsg = '';
+
+ public function __construct($apiKey, $apiSecret, $store = null)
+ {
+ $this->apiKey = $apiKey;
+ $this->apiSecret = $apiSecret;
+ $this->setStore($store);
+ }
+
+ public function errcode()
+ {
+ return $this->errcode;
+ }
+
+ public function errmsg()
+ {
+ return $this->errmsg;
+ }
+
+ /**
+ * Get Baidu Open API response format
+ *
+ * @return string The open api response format
+ */
+ public function getFormat()
+ {
+ return $this->format;
+ }
+
+ /**
+ * Set the format of Baidu Open API response
+ *
+ * @param $format open api response format, 'json' or 'xml'
+ * @return BaseBaidu
+ */
+ public function setFormat($format)
+ {
+ $this->format = $format;
+ return $this;
+ }
+
+ /**
+ * Get the final encoding of the client.
+ *
+ * @return string Final encoding of the client.
+ */
+ public function getFinalEncode()
+ {
+ return $this->finalEncode;
+ }
+
+ /**
+ * Set the final encoding of the client.
+ *
+ * @param string $finalEncode 'UTF-8' or 'GBK'
+ * @return BaseBaidu
+ */
+ public function setFinalEncode($finalEncode)
+ {
+ $this->finalEncode = $finalEncode;
+ return $this;
+ }
+
+ /**
+ * Check whether to use POST method for openapi calls.
+ *
+ * @return bool Returns true if use POST method, or false if not.
+ */
+ public function isUsingPost()
+ {
+ return $this->httpMethod == 'POST';
+ }
+
+ /**
+ * Set whether to use POST method or not for openapi calls.
+ *
+ * @param bool $flag true if want to use POST, otherwise use false
+ * @return BaseBaidu
+ */
+ public function usePost($flag = true)
+ {
+ $this->httpMethod = $flag ? 'POST' : 'GET';
+ return $this;
+ }
+
+ /**
+ * Check whether to use https or not for openapi calls.
+ *
+ * @return bool Returns true if use https, or false if not.
+ */
+ public function isUsingHttps()
+ {
+ return $this->useHttps;
+ }
+
+ /**
+ * Set whether to use https or not for openapi calls.
+ *
+ * @param bool $flag true if want to use https, otherwise use false
+ * @return BaseBaidu
+ */
+ public function useHttps($flag = true)
+ {
+ $this->useHttps = true;
+ return $this;
+ }
+
+ /**
+ * Set the session data storage instance.
+ * @param BaiduStore $store
+ */
+ public function setStore($store)
+ {
+ $this->store = $store;
+ if ($this->store) {
+ $state = $this->store->get('state');
+ if (!empty($state)) {
+ $this->state = $state;
+ }
+ $this->getSession();
+ $this->establishCSRFTokenState();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get user session.
+ *
+ * @return array
+ */
+ public function getSession()
+ {
+ if ($this->session === null) {
+ $this->session = $this->doGetSession();
+ }
+
+ return $this->session;
+ }
+
+ /**
+ * Set user session.
+ *
+ * @param array $session User session info.
+ * @return BaseBaidu
+ */
+ public function setSession($session)
+ {
+ $this->session = $session;
+ if ($session) {
+ $this->store->set('session', $session);
+ } else {
+ $this->store->remove('session');
+ }
+ return $this;
+ }
+
+ /**
+ * Get access token for openapi calls based on https.
+ *
+ * @return mixed Returns access token if user has authorized the app, or false if not.
+ */
+ public function getAccessToken()
+ {
+ $session = $this->getSession();
+ if (isset($session['access_token'])) {
+ return $session['access_token'];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get refresh token.
+ *
+ * @return mixed Returns refresh token if app has, or false if not.
+ */
+ public function getRefreshToken()
+ {
+ $session = $this->getSession();
+ if (isset($session['refresh_token'])) {
+ return $session['refresh_token'];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get session key for openapi calls based on http.
+ *
+ * @return mixed Returns session key if user has authorized the app, or false if not.
+ */
+ public function getSessionKey()
+ {
+ $session = $this->getSession();
+ if (isset($session['session_key'])) {
+ return $session['session_key'];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get session secret for openapi calls based on http.
+ *
+ * @return mixed Returns session secret if user has authorized the app, of false if not.
+ */
+ public function getSessionSecret()
+ {
+ $session = $this->getSession();
+ if (isset($session['session_secret'])) {
+ return $session['session_secret'];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get currently logged in user's uid.
+ */
+ public function getLoggedInUser()
+ {
+ // Get user from cached data or from access token
+ $user = $this->getUser();
+
+ // If there's bd_sig & bd_user parameter in query parameters,
+ // it must be an inside web app(app on baidu) loading request,
+ // then we must check whether the uid passed from baidu is the
+ // same as we get from persistent data or from access token,
+ // if it's not, we should clear all the persistent data and to
+ // get an access token again.
+ if (isset($_REQUEST['bd_sig']) && isset($_REQUEST['bd_user'])) {
+ $sig = self::generateSign(
+ array('bd_user' => $_REQUEST['bd_user']),
+ $this->apiSecret, 'bd_sig');
+ if ($sig != $_REQUEST['bd_sig'] ||
+ $user['uid'] != $_REQUEST['bd_user']) {
+ $this->store->remove('session');
+ }
+ }
+
+ return $user;
+ }
+
+ /**
+ * Get a Login URL for use with redirects. By default, full page redirect is
+ * assumed. If you are using the generated URL with a window.open() call in
+ * JavaScript, you can pass in display=popup as part of the $params.
+ *
+ * The parameters:
+ * - response_type: 'token' or 'code'
+ * - redirect_uri: the url to go to after a successful login
+ * - scope: blank space separated list of requested extended perms
+ * - display: login page style, 'page', 'popup', 'touch' or 'mobile'
+ *
+ * @param Array $params provide custom parameters
+ * @return String the URL for the login flow
+ */
+ public function getLoginUrl($params = array())
+ {
+ $currentUrl = $this->getCurrentUrl();
+
+ $params = array_merge(array('response_type' => 'token',
+ 'client_id' => $this->apiKey,
+ 'redirect_uri' => $currentUrl,
+ 'scope' => '',
+ 'state' => $this->state,
+ 'display' => 'page',
+ ), $params);
+ return self::$BD_OAUTH2_ENDPOINTS['authorize'] . '?' . http_build_query($params, '', '&');
+ }
+
+ /**
+ * Get a Logout URL suitable for use with redirects.
+ *
+ * The parameters:
+ * - next: the url to go to after a successful logout
+ * - access_token: the access token for current user
+ *
+ * @param Array $params provide custom parameters
+ * @return String the URL for the logout flow
+ */
+ public function getLogoutUrl($params = array())
+ {
+ $params = array_merge(array('access_token' => $this->getAccessToken(),
+ 'next' => $this->getCurrentUrl()), $params);
+ return self::$BD_OAUTH2_ENDPOINTS['logout'] . '?' . http_build_query($params, '', '&');
+ }
+
+ /*******************************************************
+ *
+ * Baidu OAuth2.0 Service Related Interfaces
+ *
+ ******************************************************/
+
+ /**
+ * Get baidu oauth2's authorization granting url.
+ *
+ * @param string $response_type Response type, 'code' or 'token'
+ * @param string $redirect_uri The url to go after user authorize the app
+ * @param string $scope Extend permissions delimited by blank space
+ * @param string $display Authorization page style, 'page', 'popup', 'touch' or 'mobile'
+ * @param string $state state parameter
+ * @return string Page url for authorization granting
+ */
+ public function getAuthorizeUrl($response_type = 'code', $redirect_uri = '', $scope = '', $display = 'popup', $state = '')
+ {
+ $params = array(
+ 'client_id' => $this->apiKey,
+ 'response_type' => $response_type,
+ 'redirect_uri' => $redirect_uri ? $redirect_uri : $this->getCurrentUrl(),
+ 'scope' => $scope,
+ 'state' => $state ? $state : $this->state,
+ 'display' => $display,
+ );
+ return self::$BD_OAUTH2_ENDPOINTS['authorize'] . '?' . http_build_query($params, '', '&');
+ }
+
+ /**
+ * Get access token ifno by authorization code.
+ *
+ * @param string $code Authorization code
+ * @param string $redirect_uri The redirect uri used when getting authorization code
+ * @return mixed returns access token info if success, or false if failed
+ */
+ public function getAccessTokenByAuthorizationCode($code, $redirect_uri = '')
+ {
+ $params = array(
+ 'grant_type' => 'authorization_code',
+ 'code' => $code,
+ 'client_id' => $this->apiKey,
+ 'client_secret' => $this->apiSecret,
+ 'redirect_uri' => $redirect_uri ? $redirect_uri : $this->getCurrentUrl(),
+ );
+ return $this->makeAccessTokenRequest($params);
+ }
+
+ /**
+ * Get access token info by password credentials
+ *
+ * @param string $username User name
+ * @param string $password User password
+ * @param string $scope Extend permissions delimited by blank space
+ * @return mixed returns access token info if success, or false if failed
+ */
+ public function getAccessTokenByPasswordCredentials($username, $password, $scope = '')
+ {
+ $params = array(
+ 'grant_type' => 'password',
+ 'username' => $username,
+ 'password' => $password,
+ 'client_id' => $this->apiKey,
+ 'client_secret' => $this->apiSecret,
+ 'scope' => $scope,
+ );
+ return $this->makeAccessTokenRequest($params);
+ }
+
+ /**
+ * Get access token info by client credentials.
+ *
+ * @param string $scope Extend permissions delimited by blank space
+ * @return mixed returns access token info if success, or false if failed.
+ */
+ public function getAccessTokenByClientCredentials($scope = '')
+ {
+ $params = array(
+ 'grant_type' => 'client_credentials',
+ 'client_id' => $this->apiKey,
+ 'client_secret' => $this->apiSecret,
+ 'scope' => $scope,
+ );
+ return $this->makeAccessTokenRequest($params);
+ }
+
+ /**
+ * Refresh access token by refresh token.
+ *
+ * @param string $refresh_token The refresh token
+ * @param string $scope Extend permissions delimited by blank space
+ * @return mixed returns access token info if success, or false if failed.
+ */
+ public function getAccessTokenByRefreshToken($refresh_token, $scope = '')
+ {
+ $params = array(
+ 'grant_type' => 'refresh_token',
+ 'refresh_token' => $refresh_token,
+ 'client_id' => $this->apiKey,
+ 'client_secret' => $this->apiSecret,
+ 'scope' => $scope,
+ );
+ return $this->makeAccessTokenRequest($params);
+ }
+
+ /**
+ * Make an oauth access token request
+ *
+ * The parameters:
+ * - client_id: The client identifier, just use api key
+ * - response_type: 'token' or 'code'
+ * - redirect_uri: the url to go to after a successful login
+ * - scope: The scope of the access request expressed as a list of space-delimited, case sensitive strings.
+ * - state: An opaque value used by the client to maintain state between the request and callback.
+ * - display: login page style, 'page', 'popup', 'touch' or 'mobile'
+ *
+ * @param array $params oauth request parameters
+ * @return mixed returns access token info if success, or false if failed
+ */
+ public function makeAccessTokenRequest($params)
+ {
+ $result = $this->makeRequest(self::$BD_OAUTH2_ENDPOINTS['token'], $params, 'POST');
+ if ($result) {
+ $result = json_decode($result, true);
+ if (isset($result['error_description'])) {
+ $this->setError($result['error'], $result['error_description']);
+ return false;
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ /*******************************************************
+ *
+ * Baidu OpenAPI Service Related Interfaces
+ *
+ ******************************************************/
+ /**
+ * Call api which need authorization.
+ *
+ * @param string $method api method name
+ * @param array $params api specific parameters
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function api($method, $params = array())
+ {
+ if ($this->useHttps) {
+ return $this->makeHttpsApiCall($method, $params);
+ } else {
+ return $this->makeHttpApiCall($method, $params);
+ }
+ }
+
+ /**
+ * Call public api which need not authorization.
+ *
+ * @param string $method api method name
+ * @param array $params api specific parameters
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function publicApi($method, $params)
+ {
+ return $this->makePublicApiCall($method, $params);
+ }
+
+ /**
+ * Make api call by https request
+ *
+ * @param string $method api method name
+ * @param array $params api specific parameters
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function makeHttpsApiCall($method, $params)
+ {
+ $url = self::$BD_OPENAPI_URL_PREFIXS['https'] . $method;
+
+ $params = array_merge(array('access_token' => $this->getAccessToken(),
+ 'format' => $this->format), $params);
+
+ return $this->makeApiCall($url, $params, $this->httpMethod);
+ }
+
+ /**
+ * Make api call by http request
+ *
+ * @param string $method api method name
+ * @param array $params api specific parameters
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function makeHttpApiCall($method, $params)
+ {
+ $url = self::$BD_OPENAPI_URL_PREFIXS['http'] . $method;
+
+ $params = array_merge(array('session_key' => $this->getSessionKey(),
+ 'timestamp' => date('Y-m-d H:i:s', time()),
+ 'format' => $this->format), $params);
+ $params['sign'] = self::generateSign($params, $this->getSessionSecret());
+
+ return $this->makeApiCall($url, $params, $this->httpMethod);
+ }
+
+ /**
+ * Make public api call by http request
+ *
+ * @param string $method api method name
+ * @param array $params api specific parameters
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function makePublicApiCall($method, $params)
+ {
+ $url = self::$BD_OPENAPI_URL_PREFIXS['public'] . $method;
+
+ return $this->makeApiCall($url, $params, $this->httpMethod);
+ }
+
+ /**
+ * Make an api call request
+ *
+ * @param string $url Url for the specified api
+ * @param array $params Parameters for the specified api
+ * @param string $httpMethod http or https method, 'GET' or 'POST'
+ * @return mixed returns array if api call success, or false if failed
+ */
+ public function makeApiCall($url, $params, $httpMethod = 'GET')
+ {
+ $result = $this->makeRequest($url, $params, $httpMethod);
+ if ($result !== false) {
+ if (strcasecmp($this->format, 'xml') === 0) {
+ $result = $this->convertXml2Array($result);
+ } else {
+ $result = $this->converJson2Array($result);
+ }
+ if (is_array($result) && isset($result['error_code'])) {
+ $this->setError($result['error_code'], $result['error_msg']);
+ return false;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Make a http request
+ *
+ * @param string $url Url to request
+ * @param array $params Parameters for the request
+ * @param string $httpMethod Http method, 'GET' or 'POST'
+ * @return mixed returns string if the request success, or false if failed
+ */
+ public function makeRequest($url, $param, $httpMethod = 'GET')
+ {
+ $useHttps = false;
+ if (stripos($url, 'https://') === 0) {
+ $useHttps = true;
+ }
+
+ // when using bae(baidu app engine) to deploy the application,
+ // just comment the following line
+ $ch = curl_init();
+ // when using bae(baidu app engine) to deploy the application,
+ // and uncomment the following two lines
+ //$fetch= new BaeFetchUrl();
+ //$ch = $fetch->getHandle();
+
+ $curl_opts = $this->curlOpts;
+
+ if ($useHttps) {
+ $curl_opts[CURLOPT_SSL_VERIFYPEER] = false;
+ //$curl_opts[CURLOPT_CAINFO] = 'ca-bundle1.crt';
+ }
+
+ //将数组转成url query
+ $param = http_build_query($param, '', '&');
+ if ($httpMethod == 'POST') {
+ $curl_opts[CURLOPT_URL] = $url;
+ $curl_opts[CURLOPT_POSTFIELDS] = $param;
+ } else {
+ $delimiter = strpos($url, '?') === false ? '?' : '&';
+ $curl_opts[CURLOPT_URL] = $url . $delimiter . $param;
+ $curl_opts[CURLOPT_POST] = false;
+ }
+
+ curl_setopt_array($ch, $curl_opts);
+ $result = curl_exec($ch);
+
+ if ($result === false) {
+ $this->setError(curl_errno($ch), curl_error($ch));
+ curl_close($ch);
+ return false;
+ } elseif (empty($result)) {
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ if ($http_code != 200) {
+ $this->setError($http_code, 'http response status code: ' . $http_code);
+ curl_close($ch);
+ return false;
+ }
+ }
+
+ curl_close($ch);
+
+ return $result;
+ }
+
+ /*******************************************************
+ *
+ * Utils functions
+ *
+ ******************************************************/
+
+ public static function generateSign($params, $secret, $namespace = 'sign')
+ {
+ $str = '';
+ ksort($params);
+ foreach ($params as $k => $v) {
+ if ($k != $namespace) {
+ $str .= "$k=$v";
+ }
+ }
+ $str .= $secret;
+ return md5($str);
+ }
+
+ public static function iconv($var, $inCharset = 'UTF-8', $outCharset = 'GBK')
+ {
+ if (is_array($var)) {
+ $rvar = array();
+ foreach ($var as $key => $val) {
+ $rvar[$key] = self::iconv($val, $inCharset, $outCharset);
+ }
+ return $rvar;
+ } elseif (is_object($var)) {
+ $rvar = null;
+ foreach ($var as $key => $val) {
+ $rvar->{$key} = self::iconv($val, $inCharset, $outCharset);
+ }
+ return $rvar;
+ } elseif (is_string($var)) {
+ return iconv($inCharset, $outCharset, $var);
+ } else {
+ return $var;
+ }
+ }
+
+ public function getCurrentUrl()
+ {
+ $protocol = 'http://';
+ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
+ $protocol = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) . '://';
+ } elseif (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
+ $protocol = 'https://';
+ }
+
+ if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
+ $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
+ } else {
+ $host = $_SERVER['HTTP_HOST'];
+ }
+
+ $currentUrl = $protocol . $host . $_SERVER['REQUEST_URI'];
+ $parts = parse_url($currentUrl);
+
+ $query = '';
+ if (!empty($parts['query'])) {
+ // drop known oauth params
+ $params = explode('&', $parts['query']);
+ $retained_params = array();
+ foreach ($params as $param) {
+ if ($this->shouldRetainParam($param)) {
+ $retained_params[] = $param;
+ }
+ }
+
+ if (!empty($retained_params)) {
+ $query = '?' . implode($retained_params, '&');
+ }
+ }
+
+ // use port if non default
+ $port = isset($parts['port']) && (($protocol === 'http://' && $parts['port'] !== 80) ||
+ ($protocol === 'https://' && $parts['port'] !== 443)) ? ':' . $parts['port'] : '';
+
+ // rebuild
+ return $protocol . $parts['host'] . $port . $parts['path'] . $query;
+ }
+
+ /**
+ * Prints to the error log if you aren't in command line mode.
+ *
+ * @param String log message
+ */
+ public static function errorLog($msg)
+ {
+ // disable error log if we are running in a CLI environment
+ if (php_sapi_name() != 'cli') {
+ error_log($msg);
+ }
+ // uncomment this if you want to see the errors on the page
+ // print 'error_log: '.$msg."\n";
+ }
+
+ /**
+ * Get current user's uid and uname.
+ *
+ * @return array array('uid' => xx, 'uname' => xx)
+ */
+ protected function getUser()
+ {
+ $session = $this->getSession();
+ if (isset($session['uid']) && isset($session['uname'])) {
+ return array('uid' => $session['uid'], 'uname' => $session['uname']);
+ } else {
+ return false;
+ }
+ }
+
+ protected function doGetSession()
+ {
+ // get authorization code from query parameters
+ $code = $this->getCode();
+ // check whether it is a CSRF attack request
+ if ($code && $code != $this->store->get('code')) {
+ $session = $this->getAccessTokenByAuthorizationCode($code);
+ if ($session) {
+
+ $this->store->set('code', $code);
+ $this->setSession($session);
+ $user = $this->api('passport/users/getLoggedInUser');
+ if ($user) {
+ $session = array_merge($session, $user);
+ $this->setSession($session);
+ }
+ return $session;
+ }
+
+ // code was bogus, so everything based on it should be invalidated.
+ $this->store->removeAll();
+ return false;
+ }
+
+ // as a fallback, just return whatever is in the persistent store
+ $session = $this->store->get('session');
+ $this->setSession($session);
+ if ($session && !isset($session['uid'])) {
+ $user = $this->api('passport/users/getLoggedInUser');
+ if ($user) {
+ $session = array_merge($session, $user);
+ $this->setSession($session);
+ }
+ }
+
+ return $session;
+ }
+
+ /**
+ * Get the authorization code from the query parameters, if it exists,
+ * otherwise return false to signal no authorization code was discoverable.
+ *
+ * @return mixed Returns the authorization code, or false if the authorization
+ * code could not be determined.
+ */
+ protected function getCode()
+ {
+ if (isset($_REQUEST['code'])) {
+ if ($this->state !== null &&
+ isset($_REQUEST['state']) &&
+ $this->state === $_REQUEST['state']) {
+ // CSRF state has done its job, so clear it
+ $this->state = null;
+ $this->store->remove('state');
+ return $_REQUEST['code'];
+ } else {
+ self::errorLog('CSRF state token does not match one provided.');
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Lays down a CSRF state token for this process.
+ *
+ * @return void
+ */
+ protected function establishCSRFTokenState()
+ {
+ if ($this->state === null) {
+ $this->state = md5(uniqid(mt_rand(), true));
+ $this->store->set('state', $this->state);
+ }
+ }
+
+ protected function setError($errcode, $errmsg)
+ {
+ $this->errcode = $errcode;
+ $this->errmsg = $errmsg;
+ }
+
+ private function shouldRetainParam($param)
+ {
+ foreach (self::$DROP_QUERY_PARAMS as $drop_query_param) {
+ if (strpos($param, $drop_query_param . '=') === 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private function converJson2Array($json)
+ {
+ $result = json_decode($json, true);
+ if (strcasecmp($this->finalEncode, 'UTF-8') !== 0) {
+ $result = self::iconv($result, 'UTF-8', $this->finalEncode);
+ }
+
+ return $result;
+ }
+
+ private function convertXml2Array($xml)
+ {
+ $sxml = simplexml_load_string($xml);
+ $result = self::convertSimpleXml2Array($sxml, $this->finalEncode);
+ return $result;
+ }
+
+ private static function convertSimpleXml2Array($sxml, $finalEncode)
+ {
+ $arr = array();
+ if ($sxml) {
+ foreach ($sxml as $k => $v) {
+ if ($sxml['list']) {
+ $arr[] = self::convertSimpleXml2Array($v, $finalEncode);
+ } else {
+ $arr[$k] = self::convertSimpleXml2Array($v, $finalEncode);
+ }
+ }
+ }
+
+ if (count($arr) > 0) {
+ return $arr;
+ } else {
+ if (strcasecmp($finalEncode, 'UTF-8') !== 0) {
+ return iconv('UTF-8', $finalEncode, $sxml);
+ } else {
+ return (string)$sxml;
+ }
+ }
+ }
+}
313 BaiduStore.php
@@ -0,0 +1,313 @@
+<?php
+/***************************************************************************
+ *
+ * Copyright (c) 2011 Baidu.com, Inc. All Rights Reserved
+ *
+ **************************************************************************/
+
+/**
+ * Baidu.php
+ *
+ *
+ * @package Baidu
+ * @author zhujt(zhujianting@baidu.com)
+ * @version $Revision: 1.0 Mon Jun 27 10:52:18 CST 2011
+ **/
+
+abstract class BaiduStore
+{
+ protected $apiKey;
+
+ public function __construct($apiKey)
+ {
+ $this->apiKey = $apiKey;
+ }
+
+ /**
+ * Get the variable value specified by the variable key name for
+ * current session user from the storage system.
+ *
+ * @param string $key Variable key name
+ * @param mix $default Default value if the key couldn't be found
+ * @return mix Returns the value for the specified key if it exists,
+ * otherwise return $default value
+ */
+ abstract public function get($key, $default = false);
+
+ /**
+ * Save the variable item specified by the variable key name into
+ * the storage system for current session user.
+ *
+ * @param string $key Variable key name
+ * @param mix $value Variable value
+ * @return bool Returns true if the saving operation is success,
+ * otherwise returns false
+ */
+ abstract public function set($key, $value);
+
+ /**
+ * Remove the stored variable item specified by the variable key name
+ * from the storage system for current session user.
+ *
+ * @param string $key Variable key name
+ * @return bool Returns true if remove success, otherwise returns false
+ */
+ abstract public function remove($key);
+
+ /**
+ * Remove all the stored variable items for current session user from
+ * the storage system.
+ *
+ * @return bool Returns true if remove success, otherwise returns false
+ */
+ abstract public function removeAll();
+
+ /**
+ * Prints to the error log if you aren't in command line mode.
+ *
+ * @param String log message
+ */
+ public static function errorLog($msg)
+ {
+ // disable error log if we are running in a CLI environment
+ if (php_sapi_name() != 'cli') {
+ error_log($msg);
+ }
+ // uncomment this if you want to see the errors on the page
+ // print 'error_log: '.$msg."\n";
+ }
+}
+
+class BaiduCookieStore extends BaiduStore
+{
+ /**
+ * Supported variable key name.
+ * @var array
+ */
+ protected static $kSupportedKeys = array(
+ 'state', 'code', 'session',
+ );
+
+ public function __construct($apiKey)
+ {
+ header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM"');
+ parent::__construct($apiKey);
+ }
+
+ public function get($key, $default = false)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to getPersistentData.');
+ return $default;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ $value = $_COOKIE[$name];
+ if ($value && $key == 'session') {
+ parse_str($value, $value);
+ }
+ if (empty($value)) {
+ $value = $default;
+ }
+
+ return $value;
+ }
+
+ public function set($key, $value)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to clearPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ if ($key == 'session') {
+ $expires = isset($value['expires_in']) ? $value['expires_in'] * 2 : 3600*24;
+ $value = http_build_query($value, '', '&');
+ } else {
+ $expires = 3600*24;
+ }
+
+ setcookie($name, $value, time() + $expires, '/');
+ $_COOKIE[$name] = $value;
+
+ return true;
+ }
+
+ public function remove($key)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to clearPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ setcookie($name, 'delete', time() - 3600*24, '/');
+ unset($_COOKIE[$name]);
+
+ return true;
+ }
+
+ public function removeAll()
+ {
+ foreach (self::$kSupportedKeys as $key) {
+ $this->remove($key);
+ }
+ return true;
+ }
+
+ protected function constructSessionVariableName($key)
+ {
+ return implode('_', array('bds', $this->apiKey, $key));
+ }
+}
+
+class BaiduSessionStore extends BaiduStore
+{
+ /**
+ * Supported variable key name.
+ * @var array
+ */
+ protected static $kSupportedKeys = array(
+ 'state', 'code', 'session',
+ );
+
+ public function __construct($apiKey)
+ {
+ if (!session_id()) {
+ session_start();
+ }
+ parent::__construct($apiKey);
+ }
+
+ public function get($key, $default = false)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to getPersistentData.');
+ return $default;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ return isset($_SESSION[$name]) ? $_SESSION[$name] : $default;
+ }
+
+ public function set($key, $value)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to setPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ $_SESSION[$name] = $value;
+ return true;
+ }
+
+ public function remove($key)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to clearPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ unset($_SESSION[$name]);
+
+ return true;
+ }
+
+ public function removeAll()
+ {
+ foreach (self::$kSupportedKeys as $key) {
+ $this->remove($key);
+ }
+ return true;
+ }
+
+ protected function constructSessionVariableName($key)
+ {
+ return implode('_', array('bds', $this->apiKey, $key));
+ }
+}
+
+class BaiduMemcachedStore extends BaiduStore
+{
+ /**
+ * Supported variable key name.
+ * @var array
+ */
+ protected static $kSupportedKeys = array(
+ 'state', 'code', 'session',
+ );
+
+ /**
+ * Memcache instance
+ * @var Memcache
+ */
+ protected $memcache;
+
+ /**
+ * Session ID for current user to distinguish with other users.
+ * @var string
+ */
+ protected $sessionId;
+
+ /**
+ * @param string $apiKey
+ * @param Memcache $memcache
+ */
+ public function __construct($apiKey, $memcache, $sessionId)
+ {
+ $this->memcache = $memcache;
+ $this->sessionId = $sessionId;
+
+ parent::__construct($apiKey);
+ }
+
+ public function get($key, $default = false)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to getPersistentData.');
+ return $default;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ $value = $this->memcache->get($name);
+ return ($value === false) ? $default : $value;
+ }
+
+ public function set($key, $value)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to setPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ return $this->memcache->set($name, $value, 0, 0);
+ }
+
+ public function remove($key)
+ {
+ if (!in_array($key, self::$kSupportedKeys)) {
+ self::errorLog('Unsupported key passed to clearPersistentData.');
+ return false;
+ }
+
+ $name = $this->constructSessionVariableName($key);
+ return $this->memcache->delete($name);
+ }
+
+ public function removeAll()
+ {
+ foreach (self::$kSupportedKeys as $key) {
+ $this->remove($key);
+ }
+ return true;
+ }
+
+ protected function constructSessionVariableName($key)
+ {
+ return implode('_', array('bds', $this->apiKey, $this->sessionId, $key));
+ }
+}
1,494 Channel.class.php
@@ -0,0 +1,1494 @@
+<?php
+/**
+ * 百度云消息通道服务 PHP SDK
+ *
+ * 本文件提供百度云消息通道服务的PHP版本SDK
+ *
+ * @author 百度移动.云事业部
+ * @copyright Copyright (c) 2012-2020 百度在线网络技术(北京)有限公司
+ * @version 2.0.0
+ * @package
+ */
+if ( ! defined ( 'API_ROOT_PATH' ) )
+{
+ define ( 'API_ROOT_PATH', dirname( __FILE__));
+}
+require_once ( API_ROOT_PATH . '/lib/RequestCore.class.php' );
+require_once ( API_ROOT_PATH . '/lib/ChannelException.class.php' );
+require_once ( API_ROOT_PATH . '/lib/BaeBase.class.php' );
+
+/**
+ *
+ * Channel
+ *
+ * Channel类提供百度云消息通道服务的PHP版本SDK,用户首先实例化这个类,设置自己的access_token,即可使用百度云消息通道服务
+ *
+ * @author 百度云消息通道服务@百度云架构部
+ *
+ * @version 1.0.0.0
+ */
+class Channel extends BaeBase
+{
+ /**
+ * 可选参数的KEY
+ *
+ * 用户关注:是
+ * 在调用Channel类的SDK方法时,根据用户的个性化需要,可能需要传入可选参数,而可选参数需要放在关联数组$optional中传入,
+ * 这里定义了$optional数组可用的KEY
+ */
+
+ /**
+ * 发起请求时的时间戳
+ *
+ * @var int TIMESTAMP
+ */
+ const TIMESTAMP = 'timestamp';
+ /**
+ * 请求过期的时间
+ *
+ * 如果不填写,默认为10分钟
+ *
+ * @var int EXPIRES
+ */
+ const EXPIRES = 'expires';
+ /**
+ * API版本号
+ *
+ * 用户一般不需要关注此项
+ *
+ * @var int VERSION
+ */
+ const VERSION = 'v';
+ /**
+ * 消息通道ID号
+ *
+ * @var int CHANNEL_ID
+ */
+ const CHANNEL_ID = 'channel_id';
+ /**
+ * 用户ID的类型
+ *
+ * 0:百度用户标识对称加密串;1:百度用户标识明文
+ *
+ * @var string USER_TYPE
+ */
+ const USER_TYPE = 'user_type';
+ /**
+ * 设备类型
+ *
+ * 1:浏览器设备;2:PC设备;3:andorid设备
+ *
+ * @var int DEVICE_TYPE
+ */
+ const DEVICE_TYPE = 'device_type';
+ /**
+ * 第几页
+ *
+ * 批量查询时,需要指定pageno,默认为第0页
+ *
+ * @var int PAGENO
+ */
+ const PAGENO = 'pageno';
+ /**
+ * 每页多少条记录
+ *
+ * 批量查询时,需要指定limit,默认为100条
+ *
+ * @var int LIMIT
+ */
+ const LIMIT = 'limit';
+ /**
+ * 消息ID json字符串
+ *
+ * @var string MSG_IDS
+ */
+ const MSG_IDS = 'msg_ids';
+ const MSG_KEYS = 'msg_keys';
+ const IOS_MESSAGES = 'ios_messages';
+ const WP_MESSAGES = 'wp_messages';
+ /**
+ * 消息类型
+ *
+ * 扩展类型字段,0:默认类型
+ *
+ * @var int MESSAGE_TYPE
+ */
+ const MESSAGE_TYPE = 'message_type';
+ /**
+ * 消息超时时间
+ *
+ * @var int MESSAGE_EXPIRES
+ */
+ const MESSAGE_EXPIRES = 'message_expires';
+
+ /**
+ * 消息广播组名称
+ *
+ * @var string GROUP_NAME
+ */
+ const GROUP_NAME = 'name';
+
+ /**
+ * 消息广播组描述
+ *
+ * @var stirng GROUP_INFO
+ */
+ const GROUP_INFO = 'info';
+
+ /**
+ * 消息广播组id
+ *
+ * @var int GROUP_ID
+ */
+ const GROUP_ID = 'gid';
+
+ /**
+ * 封禁时间
+ *
+ * @var int BANNED_TIME
+ */
+ const BANNED_TIME = 'banned_time';
+
+ /**
+ * 回调域名
+ *
+ * @var string CALLBACK_DOMAIN
+ */
+ const CALLBACK_DOMAIN = 'domain';
+
+ /**
+ * 回调uri
+ *
+ * @var string CALLBACK_URI
+ */
+ const CALLBACK_URI = 'uri';
+
+ /**
+ * Channel常量
+ *
+ * 用户关注:否
+ */
+ const APPID = 'appid';
+ const ACCESS_TOKEN = 'access_token';
+ const ACCESS_KEY = 'client_id';
+ const SECRET_KEY = 'client_secret';
+ const SIGN = 'sign';
+ const METHOD = 'method';
+ const HOST = 'host';
+ const USER_ID = 'user_id';
+ const MESSAGES = 'messages';
+ const PRODUCT = 'channel';
+
+ const DEFAULT_HOST = 'channel.api.duapp.com';
+ const NAME = "name";
+ const DESCRIPTION = "description";
+ const CERT = "cert";
+ const RELEASE_CERT = "release_cert";
+ const DEV_CERT = "dev_cert";
+
+ /**
+ * Channel私有变量
+ *
+ * 用户关注:否
+ */
+ protected $_accessToken = NULL;
+ protected $_requestId = 0;
+ protected $_curlOpts = array(
+ CURLOPT_TIMEOUT => 30,
+ CURLOPT_CONNECTTIMEOUT => 5
+ );
+
+ /**
+ * Channel 错误常量
+ *
+ * 用户关注:否
+ */
+ const CHANNEL_SDK_SYS = 1;
+ const CHANNEL_SDK_INIT_FAIL = 2;
+ const CHANNEL_SDK_PARAM = 3;
+ const CHANNEL_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR = 4;
+ const CHANNEL_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR = 5;
+
+ /**
+ * 错误常量与错误字符串的映射
+ *
+ * 用户关注:否
+ */
+ protected $_arrayErrorMap = array
+ (
+ '0' => 'php sdk error',
+ self::CHANNEL_SDK_SYS => 'php sdk error',
+ self::CHANNEL_SDK_INIT_FAIL => 'php sdk init error',
+ self::CHANNEL_SDK_PARAM => 'lack param',
+ self::CHANNEL_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR => 'http status is error, and the body returned is not a json string',
+ self::CHANNEL_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR => 'http status is ok, but the body returned is not a json string',
+ );
+
+ public function setAccessToken ( $accessToken )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ if ( $this->_checkString ( $accessToken, 1, 256 ) )
+ {
+ $this->_accessToken = $accessToken;
+ }
+ else
+ {
+ throw new ChannelException ( "invaid accessToken ( ${accessToken} ), which must be a 1 - 256 length string", self::CHANNEL_SDK_INIT_FAIL );
+ }
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * setCurlOpts
+ *
+ * 用户关注:是
+ * 服务类方法, 设置HTTP交互的OPTION,同PHP curl库的所有opt参数
+ *
+ * @access public
+ * @param array $arr_curlopt
+ * @return 成功:true,失败:false
+ * @throws BcmsException
+ *
+ * @version 1.2.0
+ */
+ public function setCurlOpts($arr_curlOpts)
+ {
+ $this->_resetErrorStatus();
+ try {
+ if (is_array($arr_curlOpts)) {
+ $this->_curlOpts = array_merge($this->_curlOpts, $arr_curlOpts);
+ }
+ else {
+ throw new ChannelException( 'invalid param - arr_curlOpts is not an array ['
+ . print_r($arr_curlOpts, true) . ']',
+ self::CHANNEL_SDK_INIT_FAIL);
+ }
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler( $ex );
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * getRequestId
+ *
+ * 用户关注:是
+ * 服务类方法,获取上次调用的request_id,如果SDK本身错误,则直接返回0
+ *
+ * @access public
+ * @return 上次调用服务器返回的request_id
+ *
+ * @version 1.0.0.0
+ */
+ public function getRequestId ( )
+ {
+ return $this->_requestId;
+ }
+
+ /**
+ * bindList
+ *
+ * 用户关注:是
+ *
+ * 供服务器端根据userId[、channelId]查询绑定信息
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::CHANNEL_ID、Channel::DEVICE_TYPE、Channel::PAGENO、Channel::LIMIT
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function queryBindList ( $userId, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'query_bindlist';
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * bindVerify
+ *
+ * 用户关注:是
+ *
+ * 校验userId[、channelId]是否已经绑定
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::CHANNEL_ID、Channel::DEVICE_TYPE
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function verifyBind ( $userId, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'verify_bind';
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * fetchMessage
+ *
+ * 用户关注:是
+ *
+ * 根据userId[、channelId]查询离线消息
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::CHANNEL_ID、Channel::PAGENO、Channel::LIMIT
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function fetchMessage ( $userId, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'fetch_msg';
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * messageCount
+ *
+ * 用户关注:是
+ *
+ * 根据userId[、channelId]查询离线消息的个数
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::CHANNEL_ID
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function messageCount ( $userId, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'fetch_msgcount';
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * deleteMessage
+ *
+ * 用户关注:是
+ *
+ * 根据userId、msgIds[、channelId]删除离线消息
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param string $msgIds 要删除哪些消息,如果是数组格式,则会自动做json_encode;
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::CHANNEL_ID
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function deleteMessage ( $userId, $msgIds, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID, self::MSG_IDS ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'delete_msg';
+ if(is_array($arrArgs [ self::MSG_IDS ])) {
+ $arrArgs [ self::MSG_IDS ] = json_encode($arrArgs [ self::MSG_IDS ]);
+ }
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID, self::MSG_IDS ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * pushMessage
+ *
+ * 用户关注:是
+ *
+ * 根据userId、msgIds[、channelId]推送离线消息
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param string $channelId 觕hannel的ID号
+ * @param string $messages 要发送的消息,如果是数组格式,则会自动做json_encode;如果是json格式给出,必须与$msgIds对应起来;
+ * @param string $msgKeys 发送的消息key,如果是数组格式,则会自动做json_encode;如果是json字符串格式给出,必须与$messages对应起来;
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::MESSAGE_TYPE、Channel::MESSAGE_EXPIRES
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function pushMessage ( $userId, $channelId, $messages, $msgKeys, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES, self::MSG_KEYS ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'pushmsg';
+ if(is_array($arrArgs [ self::MESSAGES ])) {
+ $arrArgs [ self::MESSAGES ] = json_encode($arrArgs [ self::MESSAGES ]);
+ }
+ if(is_array($arrArgs [ self::MSG_KEYS ])) {
+ $arrArgs [ self::MSG_KEYS ] = json_encode($arrArgs [ self::MSG_KEYS ]);
+ }
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES, self::MSG_KEYS ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * pushMessageToUser
+ *
+ * 用户关注:是
+ *
+ * 根据userId推送离线消息
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param string $messages 要发送的消息,如果是数组格式,则会自动做json_encode;如果是json格式给出,必须与$msgIds对应起来;
+ * @param string $msgKeys 发送的消息key,如果是数组格式,则会自动做json_encode;如果是json字符串格式给出,必须与$messages对应起来;
+ * @param array $optional 可选参数,支持的可选参数包括:Channel::IOS_MESSAGES、Channel::WP_MESSAGES、Channel::DEVICE_TYPE、Channel::MESSAGE_TYPE、Channel::MESSAGE_EXPIRES
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function pushMessageToUser ( $userId, $messages, $msgKeys, $optional = NULL )
+ {
+ $this->_resetErrorStatus ( );
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID, self::MESSAGES, self::MSG_KEYS ), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'pushmsg_to_user';
+ if(is_array($arrArgs [ self::MESSAGES ])) {
+ $arrArgs [ self::MESSAGES ] = json_encode($arrArgs [ self::MESSAGES ]);
+ }
+ if(is_array($arrArgs [ self::MSG_KEYS ])) {
+ $arrArgs [ self::MSG_KEYS ] = json_encode($arrArgs [ self::MSG_KEYS ]);
+ }
+ if(isset($arrArgs [ self::IOS_MESSAGES ]) && is_array($arrArgs [ self::IOS_MESSAGES ])) {
+ $msgs = array();
+ foreach ( $arrArgs[self::IOS_MESSAGES] as $message ) {
+ array_push($msgs, json_encode($message));
+ }
+ $arrArgs [ self::IOS_MESSAGES ] = json_encode($msgs);
+ }
+ if(isset($arrArgs [ self::WP_MESSAGES ]) && is_array($arrArgs [ self::WP_MESSAGES ])) {
+ $msgs = array();
+ foreach ( $arrArgs[self::WP_MESSAGES] as $message ) {
+ array_push($msgs, json_encode($message));
+ }
+ $arrArgs [ self::WP_MESSAGES ] = json_encode($msgs);
+ }
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID, self::MESSAGES, self::MSG_KEYS ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * pushIosMessage
+ *
+ * 用户关注:是
+ *
+ * 根据userId、channelId、messages 推送消息,仅支持ios设备
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param string $channelId 觕hannel的ID号
+ * @param string $messages 要发送的消息,如果是数组格式,则会自动做json_encode
+ * @param array $optional 可选参数,支持的可选参数包括 self::USER_TYPE
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+
+ public function pushIosMessage($userId, $channelId, $messages, $optional = NULL)
+ {
+
+ $this->_resetErrorStatus();
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'push_ios_msg';
+ if(is_array($arrArgs [ self::MESSAGES ])) {
+ $msgs = array();
+ foreach ( $arrArgs[self::MESSAGES] as $message ) {
+ array_push($msgs, json_encode($message));
+ }
+ $arrArgs [ self::MESSAGES ] = json_encode($msgs);
+ }
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+
+ }
+
+ /**
+ * pushWpMessage
+ *
+ * 用户关注:是
+ *
+ * 根据userId、channelId、messages 推送消息,仅支持windows phone设备
+ *
+ * @access public
+ * @param string $userId 用户ID号
+ * @param string $channelId channel的ID号
+ * @param string $messages 要发送的消息,如果是数组格式,则会自动做json_encode
+ * @param array $optional 可选参数,支持的可选参数包括 self::USER_TYPE
+ * @return 成功:PHP数组;失败:false
+ *
+ * @version 1.0.0.0
+ */
+ public function pushWpMessage($userId, $channelId, $messages, $optional = NULL)
+ {
+ $this->_resetErrorStatus();
+ try
+ {
+ $tmpArgs = func_get_args ( );
+ $arrArgs = $this->_mergeArgs ( array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES), $tmpArgs );
+ $arrArgs [ self::METHOD ] = 'push_wp_msg';
+ if(is_array($arrArgs [ self::MESSAGES ])) {
+ $msgs = array();
+ foreach ( $arrArgs[self::MESSAGES] as $message ) {
+ array_push($msgs, json_encode($message));
+ }
+ $arrArgs [ self::MESSAGES ] = json_encode($msgs);
+ }
+ return $this->_commonProcess ( $arrArgs, array ( self::USER_ID, self::CHANNEL_ID, self::MESSAGES ) );
+ }
+ catch ( Exception $ex )
+ {
+ $this->_channelExceptionHandler ( $ex );
+ return false;
+ }
+ }
+
+ /**
+ * createGroup: 创建消息广播组
+ *
+ * 用户关注: 是
+ *
+ * @access public
+ * @param string $groupName 广播组名称
+ * @param array $optional 可选参数,支持的可选参数包括 self::GROUP_INFO
+ * @return 成功: array; 失败: false
+ *
+ * @version 1.0.0.0
+ */
+ public function createGroup($groupName, $optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(self::GROUP_NAME), $tmpArgs);
+ $arrArgs[self::METHOD] = 'create_group';
+ return $this->_commonProcess($arrArgs, array(self::GROUP_NAME));
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * queryGroup: 查询广播组信息
+ *
+ * 用户关注: 是
+ *
+ * @param int $groupId 广播组ID号
+ * @param array $optional
+ * @return 成功:PHP数组;失败:false
+ */
+ public function queryGroup($groupId, $optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(self::GROUP_ID), $tmpArgs);
+ $arrArgs[self::METHOD] = 'query_group';
+ return $this->_commonProcess($arrArgs, array(self::GROUP_ID));
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * destroyGroup: 删除广播组
+ *
+ * 用户关注: 是
+ *
+ * @param int $groupId 广播组ID号
+ * @param array $optional
+ * @return 成功:PHP数组;失败:false
+ */
+ public function destroyGroup($groupId, $optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(self::GROUP_ID), $tmpArgs);
+ $arrArgs[self::METHOD] = 'destroy_group';
+ return $this->_commonProcess($arrArgs, array(self::GROUP_ID));
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * queryUserGroup: 查询用户相关的广播组
+ *
+ * 用户关注: 是
+ *
+ * @param string $userId 用户ID号
+ * @param array $optional
+ * @return 成功:PHP数组;失败:false
+ */
+ public function queryUserGroup($userId, $optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(self::USER_ID), $tmpArgs);
+ $arrArgs[self::METHOD] = 'query_user_group';
+ return $this->_commonProcess($arrArgs, array(self::USER_ID));
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * pushGroupMsg: 向广播组推送消息
+ *
+ * 用户关注: 是
+ *
+ * @param string $messages 要发送的消息,如果是数组格式,则会自动做json_encode;如果是json格式给出,必须与$msgIds对应起来;
+ * @param string $msgKeys 发送的消息key,如果是数组格式,则会自动做json_encode;如果是json字符串格式给出,必须与$messages对应起来;
+ * @param array $optional可选参数,支持的可选参数包括 self::GROUP_ID, self::MESSAGE_EXPIRES
+ * @return 成功:PHP数组;失败:false
+ */
+ public function pushGroupMsg($messages, $msgKeys, $deviceType, $optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(self::MESSAGES, self::MSG_KEYS, self::DEVICE_TYPE), $tmpArgs);
+ $arrArgs[self::METHOD] = 'push_group_msg';
+ if(is_array($arrArgs [ self::MESSAGES ])) {
+ $arrArgs [ self::MESSAGES ] = json_encode($arrArgs [ self::MESSAGES ]);
+ }
+ if(is_array($arrArgs [ self::MSG_KEYS ])) {
+ $arrArgs [ self::MSG_KEYS ] = json_encode($arrArgs [ self::MSG_KEYS ]);
+ }
+ return $this->_commonProcess($arrArgs, array(self::MESSAGES, self::MSG_KEYS, self::DEVICE_TYPE));
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * fetchGroupMsg: 查询用户广播组消息
+ *
+ * 用户关注: 是
+ *
+ * @param array $optional可选参数,支持的可选参数包括 self::USER_ID, self::CHANNEL_ID, self::GROUP_ID, self::PAGENO, self::LIMIT
+ * @return 成功:PHP数组;失败:false
+ */
+ public function fetchGroupMsg($optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(), $tmpArgs);
+ $arrArgs[self::METHOD] = 'fetch_group_msg';
+ return $this->_commonProcess($arrArgs, array());
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**
+ * fetchGroupMsgcount: 查询用户广播组消息个数
+ *
+ * 用户关注: 是
+ *
+ * @param array $optional可选参数,支持的可选参数包括 self::USER_ID, self::CHANNEL_ID, self::GROUP_ID
+ * @return 成功:PHP数组;失败:false
+ */
+ public function fetchGroupMsgcount($optional = null)
+ {
+ $this->_resetErrorStatus();
+ try {
+ $tmpArgs = func_get_args();
+ $arrArgs = $this->_mergeArgs(array(), $tmpArgs);
+ $arrArgs[self::METHOD] = 'fetch_group_msgcount';
+ return $this->_commonProcess($arrArgs, array());
+ } catch (Exception $ex) {
+ $this->_channelExceptionHandler($ex);
+ return false;
+ }
+ }
+
+ /**