提交的内容

This commit is contained in:
2025-05-12 15:45:02 +08:00
parent 629c4750da
commit b48c692775
3043 changed files with 34732 additions and 60810 deletions

79
vendor/w7corp/easywechat/src/OfficialAccount/AccessToken.php vendored Executable file → Normal file
View 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
View 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
View 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
View File

0
vendor/w7corp/easywechat/src/OfficialAccount/Contracts/Account.php vendored Executable file → Normal file
View File

View File

13
vendor/w7corp/easywechat/src/OfficialAccount/JsApiTicket.php vendored Executable file → Normal file
View 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
View File

23
vendor/w7corp/easywechat/src/OfficialAccount/Server.php vendored Executable file → Normal file
View 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
View 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