Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
leo108 committed Aug 25, 2017
1 parent e3026c1 commit f9bb6e6
Show file tree
Hide file tree
Showing 12 changed files with 599 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/vendor/
composer.lock
.idea
17 changes: 17 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "leo108/qq-exmail-sdk",
"description": "新版QQ企业邮箱SDK",
"type": "library",
"require": {
"leo108/php_sdk_skeleton": "^0.0.1",
"psr/simple-cache": "^1.0",
"cache/array-adapter": "^1.0"
},
"license": "MIT",
"authors": [
{
"name": "leo108",
"email": "leo108@qq.com"
}
]
}
58 changes: 58 additions & 0 deletions src/Core/AccessToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/25
* Time: 16:47
*/

namespace Leo108\QQExmail\Core;

use Leo108\QQExmail\Core\Exceptions\GetAccessTokenException;
use Leo108\WorkWechat\Core\BaseApi;

class AccessToken extends BaseApi
{
const API_GET_TOKEN = 'gettoken';

public function getToken($refresh = false)
{
$cacheKey = $this->getCacheKey();
$cache = $this->getSDK()->getCache();
if ($refresh || !$ret = $cache->get($cacheKey)) {
$token = $this->getTokenFromServer();
$cache->set($cacheKey, $token['access_token'], $token['expires_in'] - 1500);

return $token['access_token'];
}

return $ret;
}

public function getTokenFromServer()
{
$ret = static::parseJson($this->apiGet(self::API_GET_TOKEN, [
'corpid' => $this->getSDK()->getCorpId(),
'corpsecret' => $this->getSDK()->getCorpSecret(),
]));
if (empty($ret['access_token'])) {
throw new GetAccessTokenException('get AccessToken fail. response: '.json_encode($ret));
}

return $ret;
}

public function getCacheKey()
{
$prefix = $this->getSDK()->getCacheKeyPrefix();
$corpId = $this->getSDK()->getCorpId();

return sprintf('%s.access_token.%s', $prefix, $corpId);
}

protected function getTokenMiddleware()
{
// disable token middleware
return null;
}
}
134 changes: 134 additions & 0 deletions src/Core/BaseApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/11
* Time: 22:06
*/

namespace Leo108\WorkWechat\Core;

use GuzzleHttp\Middleware;
use Leo108\QQExmail\Core\Middleware\CheckApiResponseMiddleware;
use Leo108\QQExmail\QQExmail;
use Leo108\SDK\AbstractApi;
use Leo108\SDK\Middleware\TokenMiddleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LogLevel;

class BaseApi extends AbstractApi
{
/**
* @var QQExmail
*/
protected $sdk;

/**
* @return QQExmail
*/
protected function getSDK()
{
return $this->sdk;
}

protected function getFullApiUrl($api)
{
return 'https://api.exmail.qq.com/cgi-bin/'.ltrim($api, '/');
}

/**
* @param ResponseInterface $response
* @return array|null
*/
public static function parseJson(ResponseInterface $response)
{
return \GuzzleHttp\json_decode($response->getBody(), true);
}

/**
* @return array
*/
protected function getHttpMiddleware()
{
return array_filter([
$this->getCheckApiResponseMiddleware(),
$this->getRetryMiddleware(),
$this->getTokenMiddleware(),
$this->getLogRequestMiddleware(),
]);
}

/**
* @return CheckApiResponseMiddleware
*/
protected function getCheckApiResponseMiddleware()
{
return new CheckApiResponseMiddleware(true, [static::class, 'parseJson']);
}

/**
* @return callable
*/
protected function getLogRequestMiddleware()
{
$logger = $this->getSDK()->getLogger();
$hideToken = $this->getSDK()->getConfig('log.hide_access_token', true);
$formatter = new MessageFormatter($this->getSDK()->getConfig('log.format', MessageFormatter::CLF), $hideToken);
$logLevel = $this->getSDK()->getConfig('log.level', LogLevel::INFO);

return Middleware::log($logger, $formatter, $logLevel);
}

/**
* @return TokenMiddleware
*/
protected function getTokenMiddleware()
{
return new TokenMiddleware(true, function (RequestInterface $request) {
return $this->attachAccessToken($request);
});
}

/**
* @return callable
*/
protected function getRetryMiddleware()
{
return Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null) {
if ($retries >= $this->getSDK()->getConfig('api_retry', 3)) {
return false;
}
if (!$response || $response->getStatusCode() >= 400) {
return true;
}

$ret = static::parseJson($response);
if (in_array($ret['errcode'], ['40001', '40014'])) {
// 刷新 access token
$this->getSDK()->accessToken->getToken(true);

return true;
}

return false;
});
}

/**
* 在请求的 url 后加上 access_token 参数
*
* @param RequestInterface $request
* @param bool $cache
*
* @return RequestInterface
*/
private function attachAccessToken(RequestInterface $request, $cache = true)
{
$query = \GuzzleHttp\Psr7\parse_query($request->getUri()->getQuery());
$query['access_token'] = $this->getSDK()->accessToken->getToken(!$cache);
$uri = $request->getUri()->withQuery(http_build_query($query));

return $request->withUri($uri);
}
}
14 changes: 14 additions & 0 deletions src/Core/Exceptions/ApiException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/14
* Time: 11:43
*/

namespace Leo108\QQExmail\Core\Exceptions;

class ApiException extends QQExmailException
{

}
14 changes: 14 additions & 0 deletions src/Core/Exceptions/GetAccessTokenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/13
* Time: 12:10
*/

namespace Leo108\QQExmail\Core\Exceptions;

class GetAccessTokenException extends QQExmailException
{

}
14 changes: 14 additions & 0 deletions src/Core/Exceptions/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/12
* Time: 13:28
*/

namespace Leo108\QQExmail\Core\Exceptions;

class InvalidArgumentException extends QQExmailException
{

}
16 changes: 16 additions & 0 deletions src/Core/Exceptions/QQExmailException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/13
* Time: 12:10
*/

namespace Leo108\QQExmail\Core\Exceptions;

use Exception;

abstract class QQExmailException extends Exception
{

}
58 changes: 58 additions & 0 deletions src/Core/MessageFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Created by PhpStorm.
* User: leo108
* Date: 2017/8/14
* Time: 18:19
*/

namespace Leo108\WorkWechat\Core;

use GuzzleHttp\MessageFormatter as BaseMessageFormatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class MessageFormatter extends BaseMessageFormatter
{
/**
* @var bool
*/
protected $hideAccessToken = true;

public function __construct($template = BaseMessageFormatter::CLF, $hideAccessToken = true)
{
parent::__construct($template);
$this->hideAccessToken = $hideAccessToken;
}

/**
* @return bool
*/
public function isHideAccessToken()
{
return $this->hideAccessToken;
}

/**
* @param bool $hideAccessToken
*/
public function setHideAccessToken($hideAccessToken)
{
$this->hideAccessToken = $hideAccessToken;
}

public function format(
RequestInterface $request,
ResponseInterface $response = null,
\Exception $error = null
) {
if ($this->isHideAccessToken()) {
$query = \GuzzleHttp\Psr7\parse_query($request->getUri()->getQuery());
$query['access_token'] = 'hidden';
$uri = $request->getUri()->withQuery(http_build_query($query));
$request = $request->withUri($uri);
}

return parent::format($request, $response, $error);
}
}
Loading

0 comments on commit f9bb6e6

Please sign in to comment.