提交的内容
This commit is contained in:
79
vendor/w7corp/easywechat/src/OfficialAccount/AccessToken.php
vendored
Executable file → Normal file
79
vendor/w7corp/easywechat/src/OfficialAccount/AccessToken.php
vendored
Executable file → Normal file
@ -6,13 +6,9 @@ namespace EasyWeChat\OfficialAccount;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken as RefreshableAccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use function intval;
|
||||
use function is_string;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use function json_encode;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use function sprintf;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
@ -23,18 +19,26 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function intval;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
|
||||
class AccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
const CACHE_KEY_PREFIX = 'official_account';
|
||||
|
||||
public function __construct(
|
||||
protected string $appId,
|
||||
protected string $secret,
|
||||
protected ?string $key = null,
|
||||
?CacheInterface $cache = null,
|
||||
?HttpClientInterface $httpClient = null,
|
||||
protected ?bool $stable = false
|
||||
) {
|
||||
$this->httpClient = $httpClient ?? HttpClient::create(['base_uri' => 'https://api.weixin.qq.com/']);
|
||||
$this->cache = $cache ?? new Psr16Cache(new FilesystemAdapter(namespace: 'easywechat', defaultLifetime: 1500));
|
||||
@ -42,7 +46,7 @@ class AccessToken implements RefreshableAccessTokenInterface
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key ?? $this->key = sprintf('official_account.access_token.%s.%s', $this->appId, $this->secret);
|
||||
return $this->key ?? $this->key = sprintf('%s.access_token.%s.%s.%s', static::CACHE_KEY_PREFIX, $this->appId, $this->secret, (int) $this->stable);
|
||||
}
|
||||
|
||||
public function setKey(string $key): static
|
||||
@ -65,7 +69,7 @@ class AccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
$token = $this->cache->get($this->getKey());
|
||||
|
||||
if ((bool) $token && is_string($token)) {
|
||||
if ($token && is_string($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
@ -73,7 +77,7 @@ class AccessToken implements RefreshableAccessTokenInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
* @return array{access_token:string}
|
||||
*
|
||||
* @throws HttpException
|
||||
* @throws InvalidArgumentException
|
||||
@ -90,15 +94,62 @@ class AccessToken implements RefreshableAccessTokenInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\HttpException
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
||||
*/
|
||||
public function refresh(): string
|
||||
{
|
||||
return $this->stable ? $this->getStableAccessToken() : $this->getAccessToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\HttpException
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
||||
*/
|
||||
public function getStableAccessToken(bool $force_refresh = false): string
|
||||
{
|
||||
$response = $this->httpClient->request(
|
||||
'POST',
|
||||
'https://api.weixin.qq.com/cgi-bin/stable_token',
|
||||
[
|
||||
'json' => [
|
||||
'grant_type' => 'client_credential',
|
||||
'appid' => $this->appId,
|
||||
'secret' => $this->secret,
|
||||
'force_refresh' => $force_refresh,
|
||||
],
|
||||
]
|
||||
)->toArray(false);
|
||||
|
||||
if (empty($response['access_token'])) {
|
||||
throw new HttpException('Failed to get stable access_token: '.json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
$this->cache->set($this->getKey(), $response['access_token'], intval($response['expires_in']));
|
||||
|
||||
return $response['access_token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\HttpException
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
||||
*/
|
||||
public function getAccessToken(): string
|
||||
{
|
||||
$response = $this->httpClient->request(
|
||||
'GET',
|
||||
|
||||
2
vendor/w7corp/easywechat/src/OfficialAccount/Account.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/OfficialAccount/Account.php
vendored
Executable file → Normal file
@ -24,7 +24,7 @@ class Account implements AccountInterface
|
||||
|
||||
public function getSecret(): string
|
||||
{
|
||||
if (null === $this->secret) {
|
||||
if ($this->secret === null) {
|
||||
throw new RuntimeException('No secret configured.');
|
||||
}
|
||||
|
||||
|
||||
25
vendor/w7corp/easywechat/src/OfficialAccount/Application.php
vendored
Executable file → Normal file
25
vendor/w7corp/easywechat/src/OfficialAccount/Application.php
vendored
Executable file → Normal file
@ -4,10 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OfficialAccount;
|
||||
|
||||
use function array_merge;
|
||||
use function call_user_func;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\JsApiTicket as JsApiTicketInterface;
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken as RefreshableAccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableJsApiTicket as RefreshableJsApiTicketInterface;
|
||||
use EasyWeChat\Kernel\Contracts\Server as ServerInterface;
|
||||
use EasyWeChat\Kernel\Encryptor;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
@ -27,18 +27,21 @@ use JetBrains\PhpStorm\Pure;
|
||||
use Overtrue\Socialite\Contracts\ProviderInterface as SocialiteProviderInterface;
|
||||
use Overtrue\Socialite\Providers\WeChat;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use function sprintf;
|
||||
use function str_contains;
|
||||
use Symfony\Component\HttpClient\Response\AsyncContext;
|
||||
use Symfony\Component\HttpClient\RetryableHttpClient;
|
||||
|
||||
use function array_merge;
|
||||
use function call_user_func;
|
||||
use function sprintf;
|
||||
use function str_contains;
|
||||
|
||||
class Application implements ApplicationInterface
|
||||
{
|
||||
use InteractWithConfig;
|
||||
use InteractWithCache;
|
||||
use InteractWithServerRequest;
|
||||
use InteractWithHttpClient;
|
||||
use InteractWithClient;
|
||||
use InteractWithConfig;
|
||||
use InteractWithHttpClient;
|
||||
use InteractWithServerRequest;
|
||||
use LoggerAwareTrait;
|
||||
|
||||
protected ?Encryptor $encryptor = null;
|
||||
@ -49,7 +52,7 @@ class Application implements ApplicationInterface
|
||||
|
||||
protected AccessTokenInterface|RefreshableAccessTokenInterface|null $accessToken = null;
|
||||
|
||||
protected ?JsApiTicket $ticket = null;
|
||||
protected ?JsApiTicketInterface $ticket = null;
|
||||
|
||||
protected ?\Closure $oauthFactory = null;
|
||||
|
||||
@ -137,6 +140,7 @@ class Application implements ApplicationInterface
|
||||
secret: $this->getAccount()->getSecret(),
|
||||
cache: $this->getCache(),
|
||||
httpClient: $this->getHttpClient(),
|
||||
stable: $this->config->get('use_stable_access_token', false),
|
||||
);
|
||||
}
|
||||
|
||||
@ -184,7 +188,7 @@ class Application implements ApplicationInterface
|
||||
return $provider;
|
||||
}
|
||||
|
||||
public function getTicket(): JsApiTicket
|
||||
public function getTicket(): JsApiTicketInterface|RefreshableJsApiTicketInterface
|
||||
{
|
||||
if (! $this->ticket) {
|
||||
$this->ticket = new JsApiTicket(
|
||||
@ -192,13 +196,14 @@ class Application implements ApplicationInterface
|
||||
secret: $this->getAccount()->getSecret(),
|
||||
cache: $this->getCache(),
|
||||
httpClient: $this->getClient(),
|
||||
stable: $this->config->get('use_stable_access_token', false),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->ticket;
|
||||
}
|
||||
|
||||
public function setTicket(JsApiTicket $ticket): static
|
||||
public function setTicket(JsApiTicketInterface|RefreshableJsApiTicketInterface $ticket): static
|
||||
{
|
||||
$this->ticket = $ticket;
|
||||
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OfficialAccount/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Contracts/Application.php
vendored
Executable file → Normal file
13
vendor/w7corp/easywechat/src/OfficialAccount/JsApiTicket.php
vendored
Executable file → Normal file
13
vendor/w7corp/easywechat/src/OfficialAccount/JsApiTicket.php
vendored
Executable file → Normal file
@ -4,11 +4,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OfficialAccount;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableJsApiTicket as RefreshableJsApiTicketInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
class JsApiTicket extends AccessToken
|
||||
class JsApiTicket extends AccessToken implements RefreshableJsApiTicketInterface
|
||||
{
|
||||
/**
|
||||
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
||||
@ -24,10 +26,15 @@ class JsApiTicket extends AccessToken
|
||||
$key = $this->getKey();
|
||||
$ticket = $this->cache->get($key);
|
||||
|
||||
if ((bool) $ticket && \is_string($ticket)) {
|
||||
if ($ticket && \is_string($ticket)) {
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
return $this->refreshTicket();
|
||||
}
|
||||
|
||||
public function refreshTicket(): string
|
||||
{
|
||||
$response = $this->httpClient->request('GET', '/cgi-bin/ticket/getticket', ['query' => ['type' => 'jsapi']])
|
||||
->toArray(false);
|
||||
|
||||
@ -35,7 +42,7 @@ class JsApiTicket extends AccessToken
|
||||
throw new HttpException('Failed to get jssdk ticket: '.\json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
$this->cache->set($key, $response['ticket'], \intval($response['expires_in']));
|
||||
$this->cache->set($this->getKey(), $response['ticket'], \intval($response['expires_in']));
|
||||
|
||||
return $response['ticket'];
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OfficialAccount/Message.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OfficialAccount/Message.php
vendored
Executable file → Normal file
23
vendor/w7corp/easywechat/src/OfficialAccount/Server.php
vendored
Executable file → Normal file
23
vendor/w7corp/easywechat/src/OfficialAccount/Server.php
vendored
Executable file → Normal file
@ -10,10 +10,10 @@ use EasyWeChat\Kernel\Encryptor;
|
||||
use EasyWeChat\Kernel\Exceptions\BadRequestException;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\Kernel\HttpClient\RequestUtil;
|
||||
use EasyWeChat\Kernel\ServerResponse;
|
||||
use EasyWeChat\Kernel\Traits\DecryptXmlMessage;
|
||||
use EasyWeChat\Kernel\Traits\InteractWithHandlers;
|
||||
use EasyWeChat\Kernel\Traits\InteractWithServerRequest;
|
||||
use EasyWeChat\Kernel\Traits\RespondXmlMessage;
|
||||
use Nyholm\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
@ -22,20 +22,16 @@ use Throwable;
|
||||
|
||||
class Server implements ServerInterface
|
||||
{
|
||||
use RespondXmlMessage;
|
||||
use DecryptXmlMessage;
|
||||
use InteractWithHandlers;
|
||||
use InteractWithServerRequest;
|
||||
use RespondXmlMessage;
|
||||
|
||||
protected ServerRequestInterface $request;
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function __construct(
|
||||
?ServerRequestInterface $request = null,
|
||||
protected ?Encryptor $encryptor = null,
|
||||
) {
|
||||
$this->request = $request ?? RequestUtil::createDefaultServerRequest();
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,12 +41,12 @@ class Server implements ServerInterface
|
||||
*/
|
||||
public function serve(): ResponseInterface
|
||||
{
|
||||
if ((bool) ($str = $this->request->getQueryParams()['echostr'] ?? '')) {
|
||||
if ($str = $this->getRequest()->getQueryParams()['echostr'] ?? '') {
|
||||
return new Response(200, [], $str);
|
||||
}
|
||||
|
||||
$message = $this->getRequestMessage($this->request);
|
||||
$query = $this->request->getQueryParams();
|
||||
$message = $this->getRequestMessage($this->getRequest());
|
||||
$query = $this->getRequest()->getQueryParams();
|
||||
|
||||
if ($this->encryptor && ! empty($query['msg_signature'])) {
|
||||
$this->prepend($this->decryptRequestMessage($query));
|
||||
@ -97,6 +93,7 @@ class Server implements ServerInterface
|
||||
|
||||
/**
|
||||
* @param array<string,string> $query
|
||||
*
|
||||
* @psalm-suppress PossiblyNullArgument
|
||||
*/
|
||||
protected function decryptRequestMessage(array $query): Closure
|
||||
@ -123,7 +120,7 @@ class Server implements ServerInterface
|
||||
*/
|
||||
public function getRequestMessage(?ServerRequestInterface $request = null): \EasyWeChat\Kernel\Message
|
||||
{
|
||||
return Message::createFromRequest($request ?? $this->request);
|
||||
return Message::createFromRequest($request ?? $this->getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +129,7 @@ class Server implements ServerInterface
|
||||
*/
|
||||
public function getDecryptedMessage(?ServerRequestInterface $request = null): \EasyWeChat\Kernel\Message
|
||||
{
|
||||
$request = $request ?? $this->request;
|
||||
$request = $request ?? $this->getRequest();
|
||||
$message = $this->getRequestMessage($request);
|
||||
$query = $request->getQueryParams();
|
||||
|
||||
|
||||
3
vendor/w7corp/easywechat/src/OfficialAccount/Utils.php
vendored
Executable file → Normal file
3
vendor/w7corp/easywechat/src/OfficialAccount/Utils.php
vendored
Executable file → Normal file
@ -10,6 +10,7 @@ use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
use function time;
|
||||
|
||||
class Utils
|
||||
@ -19,10 +20,8 @@ class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array<string> $jsApiList
|
||||
* @param array<string> $openTagList
|
||||
* @param bool $debug
|
||||
* @return array<string, mixed>
|
||||
*
|
||||
* @throws HttpException
|
||||
|
||||
Reference in New Issue
Block a user