diff --git a/composer.json b/composer.json index f30e802e3..6c0fdbcef 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,11 @@ "email": "anzhengchao@gmail.com" } ], + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, "minimum-stability" : "dev", "autoload": { "psr-4": { diff --git a/src/Wechat/AccessToken.php b/src/Wechat/AccessToken.php index b461a057c..aebb0f781 100644 --- a/src/Wechat/AccessToken.php +++ b/src/Wechat/AccessToken.php @@ -62,14 +62,22 @@ class AccessToken /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->appId = $appId; - $this->appSecret = $appSecret; - $this->cache = new Cache($appId); + $this->appId = $config['app_id']; + $this->appSecret = $config['secret']; + $this->cache = new Cache($this->appId); } /** diff --git a/src/Wechat/Auth.php b/src/Wechat/Auth.php index ac4cb3607..ce6b05a72 100644 --- a/src/Wechat/Auth.php +++ b/src/Wechat/Auth.php @@ -74,13 +74,12 @@ class Auth /** * constructor * - * @param string $appId - * @param string $appSecret + * @param array $config */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->appId = $appId; - $this->appSecret = $appSecret; + $this->appId = $config['app_id']; + $this->appSecret = $config['secret']; $this->http = new Http(); // 不需要公用的access_token $this->input = new Input(); } diff --git a/src/Wechat/Card.php b/src/Wechat/Card.php index a8b8ecf9a..b4c99d812 100644 --- a/src/Wechat/Card.php +++ b/src/Wechat/Card.php @@ -80,13 +80,21 @@ class Card /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); - $this->cache = new Cache($appId); + $this->http = new Http(new AccessToken($config)); + $this->cache = new Cache($config['app_id']); } /** diff --git a/src/Wechat/Color.php b/src/Wechat/Color.php index 161122541..18bce16dd 100644 --- a/src/Wechat/Color.php +++ b/src/Wechat/Color.php @@ -40,13 +40,21 @@ class Color /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); - $this->cache = new Cache($appId); + $this->http = new Http(new AccessToken($config)); + $this->cache = new Cache($config['app_id']); } /** diff --git a/src/Wechat/Crypt.php b/src/Wechat/Crypt.php index 5ec62b006..914b9ad46 100644 --- a/src/Wechat/Crypt.php +++ b/src/Wechat/Crypt.php @@ -69,26 +69,26 @@ class Crypt + + /** * constructor * - * @param string $appId - * @param string $token - * @param string $encodingAESKey + * @param array $config */ - public function __construct($appId, $token, $encodingAESKey) + public function __construct(array $config) { if (!extension_loaded('mcrypt')) { throw new Exception('Mcrypt 拓展未安装或未启用'); } - if (strlen($encodingAESKey) !== 43) { + if (strlen($config['encoding_key']) !== 43) { throw new Exception('Invalid AESKey.', self::ERROR_INVALID_AESKEY); } - $this->appId = $appId; - $this->token = $token; - $this->AESKey = base64_decode($encodingAESKey.'=', true); + $this->appId = $config['app_id']; + $this->token = $config['token']; + $this->AESKey = base64_decode($config['encoding_key'].'=', true); $this->blockSize = 32;// mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); } diff --git a/src/Wechat/Exception.php b/src/Wechat/Exception.php index fc111827d..24eaccffe 100644 --- a/src/Wechat/Exception.php +++ b/src/Wechat/Exception.php @@ -175,5 +175,5 @@ public function __construct($message, $code = -1) $message = "[Wechat]{$message}"; parent::__construct($message, $code); - } + } } diff --git a/src/Wechat/Group.php b/src/Wechat/Group.php index e08d1a166..c8b8fab2f 100644 --- a/src/Wechat/Group.php +++ b/src/Wechat/Group.php @@ -38,12 +38,20 @@ class Group /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** @@ -106,9 +114,7 @@ public function update($groupId, $name) public function delete($groupId) { $params = array( - 'group' => array( - 'id' => $groupId, - ), + 'group' => array('id' => $groupId), ); return $this->http->jsonPost(self::API_DELETE, $params); diff --git a/src/Wechat/Image.php b/src/Wechat/Image.php index dd713d39c..fa81c0672 100644 --- a/src/Wechat/Image.php +++ b/src/Wechat/Image.php @@ -32,12 +32,20 @@ class Image /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Js.php b/src/Wechat/Js.php index 2e8136d3d..d5c04820b 100644 --- a/src/Wechat/Js.php +++ b/src/Wechat/Js.php @@ -56,13 +56,12 @@ class Js /** * constructor * - * @param string $appId - * @param string $appSecret + * @param array $config */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->appId = $appId; - $this->appSecret = $appSecret; + $this->appId = $config['app_id']; + $this->appSecret = $config['secret']; $this->cache = new Cache($appId); } @@ -119,7 +118,7 @@ public function getTicket() return $this->cache->get( $key, function ($key) use ($appId, $appSecret, $cache, $apiTicket) { - $http = new Http(new AccessToken($appId, $appSecret)); + $http = new Http(new AccessToken(array('app_id' => $appId, 'secret' => $appSecret))); $result = $http->get($apiTicket); diff --git a/src/Wechat/Media.php b/src/Wechat/Media.php index 738ed01b9..e9132e6fe 100644 --- a/src/Wechat/Media.php +++ b/src/Wechat/Media.php @@ -67,12 +67,20 @@ class Media /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Menu.php b/src/Wechat/Menu.php index 75ed01c99..c70c30d8c 100644 --- a/src/Wechat/Menu.php +++ b/src/Wechat/Menu.php @@ -38,12 +38,20 @@ class Menu /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Messages/Voice.php b/src/Wechat/Messages/Voice.php index 36b5ce53d..a25d9680c 100644 --- a/src/Wechat/Messages/Voice.php +++ b/src/Wechat/Messages/Voice.php @@ -39,27 +39,16 @@ class Voice extends BaseMessage */ protected $media; - /** - * constructor - * - * @param string $appId - * @param string $appSecret - */ - public function __construct($appId, $appSecret) - { - $this->media = new Media($appId, $appSecret); - } - /** * 设置语音 * - * @param string $path + * @param string $mediaId * * @return Voice */ - public function media($path) + public function media($mediaId) { - $this->setAttribute('media_id', $this->media->voice($path)); + $this->setAttribute('media_id', $mediaId); return $this; } diff --git a/src/Wechat/Notice.php b/src/Wechat/Notice.php index b52d8ffa9..b6057eb68 100644 --- a/src/Wechat/Notice.php +++ b/src/Wechat/Notice.php @@ -140,12 +140,20 @@ class Notice /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/QRCode.php b/src/Wechat/QRCode.php index 7adbaad5c..6db38e76d 100644 --- a/src/Wechat/QRCode.php +++ b/src/Wechat/QRCode.php @@ -26,16 +26,9 @@ class QRCode /** * 应用ID * - * @var string + * @var Http */ - protected $appId; - - /** - * 应用secret - * - * @var string - */ - protected $appSecret; + protected $http; const DAY = 86400; const SCENE_QE_CARD = 'QR_CARD'; // 卡券 @@ -49,13 +42,20 @@ class QRCode /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->appId = $appId; - $this->appSecret = $appSecret; + $this->http = new Http(new AccessToken($config)); } /** @@ -156,8 +156,6 @@ protected function create($actionName, $actionInfo, $temporary = true, $expireSe { $expireSeconds !== null || $expireSeconds = 7 * self::DAY; - $http = new Http(new AccessToken($this->appId, $this->appSecret)); - $params = array( 'action_name' => $actionName, 'action_info' => array('scene' => $actionInfo), @@ -167,6 +165,6 @@ protected function create($actionName, $actionInfo, $temporary = true, $expireSe $params['expire_seconds'] = min($expireSeconds, 7 * self::DAY); } - return new Bag($http->jsonPost(self::API_CREATE, $params)); + return new Bag($this->http->jsonPost(self::API_CREATE, $params)); } } diff --git a/src/Wechat/Semantic.php b/src/Wechat/Semantic.php index 668f3734f..bd578cbfb 100644 --- a/src/Wechat/Semantic.php +++ b/src/Wechat/Semantic.php @@ -42,13 +42,21 @@ class Semantic /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->appId = $appId; - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->appId = $config['app_id']; + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Server.php b/src/Wechat/Server.php index d6a31b1f6..99e7d5f4e 100644 --- a/src/Wechat/Server.php +++ b/src/Wechat/Server.php @@ -26,18 +26,11 @@ class Server { /** - * 应用ID + * 配置 * - * @var string - */ - protected $appId; - - /** - * token - * - * @var string + * @var array */ - protected $token; + protected $config; /** * encodingAESKey @@ -81,16 +74,12 @@ class Server /** * constructor * - * @param string $appId - * @param string $token - * @param string $encodingAESKey + * @param array $config */ - public function __construct($appId, $token, $encodingAESKey = null) + public function __construct(array $config) { - $this->listeners = new Bag(); - $this->appId = $appId; - $this->token = $token; - $this->encodingAESKey = $encodingAESKey; + $this->listeners = new Bag(); + $this->config = $config; } /** @@ -160,7 +149,7 @@ public function serve() $this->prepareInput(); $input = array( - $this->token, + $this->config['token'], $this->input->get('timestamp'), $this->input->get('nonce'), ); @@ -233,11 +222,11 @@ protected function getCrypt() static $crypt; if (!$crypt) { - if (empty($this->encodingAESKey) || empty($this->token)) { + if (empty($this->config['encoding_key']) || empty($this->config['token'])) { throw new Exception("加密模式下 'encodingAESKey' 与 'token' 都不能为空!"); } - $crypt = new Crypt($this->appId, $this->token, $this->encodingAESKey); + $crypt = new Crypt($this->config); } return $crypt; @@ -387,14 +376,4 @@ public function __call($method, $args) return; } } - - /** - * 直接返回以字符串形式输出时 - * - * @return string - */ - public function __toString() - { - return ''.$this->serve(); - } -} +} // end class diff --git a/src/Wechat/Staff.php b/src/Wechat/Staff.php index d919e3646..7164bcce5 100644 --- a/src/Wechat/Staff.php +++ b/src/Wechat/Staff.php @@ -62,12 +62,20 @@ class Staff /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Stats.php b/src/Wechat/Stats.php index ae0cbed3e..328d3a352 100644 --- a/src/Wechat/Stats.php +++ b/src/Wechat/Stats.php @@ -66,12 +66,20 @@ class Stats /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Store.php b/src/Wechat/Store.php index 8c5fa0107..014de7adb 100644 --- a/src/Wechat/Store.php +++ b/src/Wechat/Store.php @@ -40,12 +40,20 @@ class Store /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Url.php b/src/Wechat/Url.php index 5fdd20570..3ac862e23 100644 --- a/src/Wechat/Url.php +++ b/src/Wechat/Url.php @@ -33,12 +33,20 @@ class Url /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/User.php b/src/Wechat/User.php index 66d6579ca..3adc2041d 100644 --- a/src/Wechat/User.php +++ b/src/Wechat/User.php @@ -39,12 +39,20 @@ class User /** * constructor * - * @param string $appId - * @param string $appSecret + *
+     * $config:
+     *
+     * array(
+     *  'app_id' => YOUR_APPID,  // string mandatory;
+     *  'secret' => YOUR_SECRET, // string mandatory;
+     * )
+     * 
+ * + * @param array $config configuration array */ - public function __construct($appId, $appSecret) + public function __construct(array $config) { - $this->http = new Http(new AccessToken($appId, $appSecret)); + $this->http = new Http(new AccessToken($config)); } /** diff --git a/src/Wechat/Utils/JSON.php b/src/Wechat/Utils/JSON.php index 7c11d4fb0..fc455b1ca 100644 --- a/src/Wechat/Utils/JSON.php +++ b/src/Wechat/Utils/JSON.php @@ -22,11 +22,13 @@ */ class JSON { + /** * To prevent new operation, under static usage only */ protected function __construct() - {} + { + } /** * PHP >= 5.3 JSON_UNESCAPED_UNICODE constant supported @@ -44,23 +46,19 @@ public static function encode($value, $options = 0, $depth = 512) // multi-characters supported by default $options |= JSON_UNESCAPED_UNICODE; - $data = version_compare(PHP_VERSION, '5.5.0', '>=') - ? json_encode($value, $options, $depth) - : json_encode($value, $options); + $data = version_compare(PHP_VERSION, '5.5.0', '>=') ? json_encode($value, $options, $depth) : json_encode($value, $options); if (JSON_ERROR_NONE !== json_last_error()) { return $data; } - return version_compare(PHP_VERSION, '5.4.0', '>=') - ? $data - : preg_replace_callback("/\\\u([0-9a-f]{2})([0-9a-f]{2})/iu", function ($pipe) { + return version_compare(PHP_VERSION, '5.4.0', '>=') ? $data : preg_replace_callback("/\\\u([0-9a-f]{2})([0-9a-f]{2})/iu", function ($pipe) { return iconv( strncasecmp(PHP_OS, 'WIN', 3) ? 'UCS-2BE' : 'UCS-2', 'UTF-8', chr(hexdec($pipe[1])) . chr(hexdec($pipe[2])) ); - }, $data); + }, $data); } /** diff --git a/src/Wechat/Wechat.php b/src/Wechat/Wechat.php new file mode 100644 index 000000000..c09a4cdfc --- /dev/null +++ b/src/Wechat/Wechat.php @@ -0,0 +1,157 @@ + + * @copyright 2015 overtrue + * @link https://github.com/overtrue + * @link http://overtrue.me + */ + +namespace Overtrue\Wechat; + +/** + * SDK 入口 + */ +class Wechat +{ + + /** + * 配置信息 + * + * @var array + * + *
+     * [
+     *   'use_alias'    => false,
+     *   'app_id'       => 'YourAppId', // 必填
+     *   'secret'       => 'YourSecret', // 必填
+     *   'token'        => 'YourToken',  // 必填
+     *   'encoding_key' => 'YourEncodingAESKey' // 加密模式需要,其它模式不需要
+     * ]
+     * 
+ */ + protected static $config; + + /** + * 已经实例化的对象 + * + * @var array + */ + protected static $resolved; + + /** + * 初始化配置 + * + * @param array $config 配置项 + * + * @return void + */ + public static function config(array $config) + { + self::$config = $config; + } + + /** + * 获取服务 + * + * @param string $name + * @param array $args + * + * @return mixed + */ + public static function service($name, $args = array()) + { + return self::build("Overtrue\\Wechat\\" . ucfirst(self::camelCase($name)), $args); + } + + /** + * 获取消息 + * + * @param string $name + * @param array $args + * + * @return mixed + */ + public static function message($name, $args = array()) + { + return self::build("Overtrue\\Wechat\\Messages\\" . ucfirst(self::camelCase($name)), $args); + } + + /** + * 获取工具对象 + * + * @param string $name + * @param array $args + * + * @return mixed + */ + public static function util($name, $args = array()) + { + return self::build("Overtrue\\Wechat\\Utils\\" . ucfirst(self::camelCase($name)), $args); + } + + /** + * 获取对象实例 + * + * @param string $class + * @param array $args + * + * @return mixed + */ + public static function build($class, $args = array()) + { + $args = array_merge(self::$config, $args); + + return self::getResolved($class, $args, function ($key) use ($class, $args) { + return self::$resolved[$key] = new $class($args); + }); + } + + /** + * 字符串转驼峰 + * + * @param string $string 字符串 + * + * @return string + */ + public static function camelCase($string) + { + return preg_replace_callback( + '/_{1,}([a-z])/', + function ($pipe) { + return strtolower($pipe[1]); + }, + $string + ); + } + + /** + * 获取已经实例化的对象 + * + * @param string $class 类名 + * @param array $args 参数 + * @param callable $callback 回调 + * + * @return mixed + */ + protected static function getResolved($class, $args, $callback = null) + { + $key = $class . md5(json_encode($args)); + + if (isset(self::$resolved[$key])) { + return self::$resolved[$key]; + } + + if (is_callable($callback)) { + return call_user_func_array($callback, array($key)); + } + + return null; + } +}