提交的内容
This commit is contained in:
25
vendor/w7corp/easywechat/src/Kernel/Config.php
vendored
Executable file → Normal file
25
vendor/w7corp/easywechat/src/Kernel/Config.php
vendored
Executable file → Normal file
@ -9,6 +9,7 @@ use EasyWeChat\Kernel\Contracts\Config as ConfigInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use EasyWeChat\Kernel\Support\Arr;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
|
||||
use function strval;
|
||||
|
||||
/**
|
||||
@ -53,7 +54,7 @@ class Config implements ArrayAccess, ConfigInterface
|
||||
|
||||
/**
|
||||
* @param array<string> $keys
|
||||
* @return array<string, mixed>
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
#[Pure]
|
||||
public function getMany(array $keys): array
|
||||
@ -71,17 +72,13 @@ class Config implements ArrayAccess, ConfigInterface
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed|null $value
|
||||
*/
|
||||
public function set(string $key, mixed $value = null): void
|
||||
{
|
||||
Arr::set($this->items, $key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
@ -89,25 +86,25 @@ class Config implements ArrayAccess, ConfigInterface
|
||||
}
|
||||
|
||||
#[Pure]
|
||||
public function offsetExists(mixed $key): bool
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return $this->has(strval($key));
|
||||
return $this->has(strval($offset));
|
||||
}
|
||||
|
||||
#[Pure]
|
||||
public function offsetGet(mixed $key): mixed
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->get(strval($key));
|
||||
return $this->get(strval($offset));
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $key, mixed $value): void
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
$this->set(strval($key), $value);
|
||||
$this->set(strval($offset), $value);
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $key): void
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
$this->set(strval($key), null);
|
||||
$this->set(strval($offset), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Contracts/AccessToken.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/AccessToken.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/AccessTokenAwareHttpClient.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/AccessTokenAwareHttpClient.php
vendored
Executable file → Normal file
4
vendor/w7corp/easywechat/src/Kernel/Contracts/Aes.php
vendored
Executable file → Normal file
4
vendor/w7corp/easywechat/src/Kernel/Contracts/Aes.php
vendored
Executable file → Normal file
@ -4,7 +4,7 @@ namespace EasyWeChat\Kernel\Contracts;
|
||||
|
||||
interface Aes
|
||||
{
|
||||
public static function encrypt(string $plaintext, string $key, string $iv = null): string;
|
||||
public static function encrypt(string $plaintext, string $key, ?string $iv = null): string;
|
||||
|
||||
public static function decrypt(string $ciphertext, string $key, string $iv = null): string;
|
||||
public static function decrypt(string $ciphertext, string $key, ?string $iv = null): string;
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Arrayable.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Arrayable.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Config.php
vendored
Executable file → Normal file
15
vendor/w7corp/easywechat/src/Kernel/Contracts/JsApiTicket.php
vendored
Normal file
15
vendor/w7corp/easywechat/src/Kernel/Contracts/JsApiTicket.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\Contracts;
|
||||
|
||||
interface JsApiTicket
|
||||
{
|
||||
public function getTicket(): string;
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function configSignature(string $url, string $nonce, int $timestamp): array;
|
||||
}
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Jsonable.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Jsonable.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/RefreshableAccessToken.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/RefreshableAccessToken.php
vendored
Executable file → Normal file
8
vendor/w7corp/easywechat/src/Kernel/Contracts/RefreshableJsApiTicket.php
vendored
Normal file
8
vendor/w7corp/easywechat/src/Kernel/Contracts/RefreshableJsApiTicket.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace EasyWeChat\Kernel\Contracts;
|
||||
|
||||
interface RefreshableJsApiTicket extends JsApiTicket
|
||||
{
|
||||
public function refreshTicket(): string;
|
||||
}
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Server.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Contracts/Server.php
vendored
Executable file → Normal file
73
vendor/w7corp/easywechat/src/Kernel/Encryptor.php
vendored
Executable file → Normal file
73
vendor/w7corp/easywechat/src/Kernel/Encryptor.php
vendored
Executable file → Normal file
@ -4,29 +4,35 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel;
|
||||
|
||||
use function base64_decode;
|
||||
use function base64_encode;
|
||||
use const OPENSSL_NO_PADDING;
|
||||
use const SORT_STRING;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\Kernel\Support\Pkcs7;
|
||||
use EasyWeChat\Kernel\Support\Str;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
use function base64_decode;
|
||||
use function base64_encode;
|
||||
use function implode;
|
||||
use function openssl_decrypt;
|
||||
use function openssl_encrypt;
|
||||
use const OPENSSL_NO_PADDING;
|
||||
use function pack;
|
||||
use function random_bytes;
|
||||
use function sha1;
|
||||
use function sort;
|
||||
use const SORT_STRING;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use Throwable;
|
||||
use function time;
|
||||
use function trim;
|
||||
use function unpack;
|
||||
|
||||
/**
|
||||
* @link https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Message_encryption_and_decryption_instructions.html
|
||||
* @link https://developer.work.weixin.qq.com/document/path/96211
|
||||
*/
|
||||
class Encryptor
|
||||
{
|
||||
public const ERROR_INVALID_SIGNATURE = -40001; // Signature verification failed
|
||||
@ -53,14 +59,15 @@ class Encryptor
|
||||
|
||||
public const ILLEGAL_BUFFER = -41003; // Illegal buffer
|
||||
|
||||
/** AES block size in bytes */
|
||||
private const BLOCK_SIZE = 16;
|
||||
|
||||
protected string $appId;
|
||||
|
||||
protected string $token;
|
||||
|
||||
protected string $aesKey;
|
||||
|
||||
protected int $blockSize = 32;
|
||||
|
||||
protected ?string $receiveId = null;
|
||||
|
||||
public function __construct(string $appId, string $token, string $aesKey, ?string $receiveId = null)
|
||||
@ -80,17 +87,45 @@ class Encryptor
|
||||
* @throws RuntimeException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function encrypt(string $plaintext, string|null $nonce = null, int|string $timestamp = null): string
|
||||
public function encrypt(string $plaintext, ?string $nonce = null, int|string|null $timestamp = null): string
|
||||
{
|
||||
return $this->encryptAsXml($plaintext, $nonce, $timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
|
||||
*/
|
||||
public function encryptAsXml(string $plaintext, ?string $nonce = null, int|string|null $timestamp = null): string
|
||||
{
|
||||
$encrypted = $this->encryptAsArray($plaintext, $nonce, $timestamp);
|
||||
|
||||
$response = [
|
||||
'Encrypt' => $encrypted['ciphertext'],
|
||||
'MsgSignature' => $encrypted['signature'],
|
||||
'TimeStamp' => $encrypted['timestamp'],
|
||||
'Nonce' => $encrypted['nonce'],
|
||||
];
|
||||
|
||||
return Xml::build($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
|
||||
*/
|
||||
public function encryptAsArray(string $plaintext, ?string $nonce = null, int|string|null $timestamp = null): array
|
||||
{
|
||||
try {
|
||||
$plaintext = Pkcs7::padding(random_bytes(16).pack('N', strlen($plaintext)).$plaintext.$this->appId, 32);
|
||||
$plaintext = Pkcs7::padding(
|
||||
random_bytes(self::BLOCK_SIZE).pack('N', strlen($plaintext)).$plaintext.$this->appId,
|
||||
blockSize: strlen($this->aesKey)
|
||||
);
|
||||
$ciphertext = base64_encode(
|
||||
openssl_encrypt(
|
||||
$plaintext,
|
||||
'aes-256-cbc',
|
||||
$this->aesKey,
|
||||
OPENSSL_NO_PADDING,
|
||||
substr($this->aesKey, 0, 16)
|
||||
iv: substr($this->aesKey, 0, self::BLOCK_SIZE)
|
||||
) ?: ''
|
||||
);
|
||||
} catch (Throwable $e) {
|
||||
@ -100,14 +135,12 @@ class Encryptor
|
||||
$nonce ??= Str::random();
|
||||
$timestamp ??= time();
|
||||
|
||||
$response = [
|
||||
'Encrypt' => $ciphertext,
|
||||
'MsgSignature' => $this->createSignature($this->token, $timestamp, $nonce, $ciphertext),
|
||||
'TimeStamp' => $timestamp,
|
||||
'Nonce' => $nonce,
|
||||
return [
|
||||
'ciphertext' => $ciphertext,
|
||||
'signature' => $this->createSignature($this->token, $timestamp, $nonce, $ciphertext),
|
||||
'timestamp' => $timestamp,
|
||||
'nonce' => $nonce,
|
||||
];
|
||||
|
||||
return Xml::build($response);
|
||||
}
|
||||
|
||||
public function createSignature(mixed ...$attributes): string
|
||||
@ -134,11 +167,11 @@ class Encryptor
|
||||
'aes-256-cbc',
|
||||
$this->aesKey,
|
||||
OPENSSL_NO_PADDING,
|
||||
substr($this->aesKey, 0, 16)
|
||||
iv: substr($this->aesKey, 0, self::BLOCK_SIZE)
|
||||
) ?: '',
|
||||
32
|
||||
blockSize: strlen($this->aesKey)
|
||||
);
|
||||
$plaintext = substr($plaintext, 16);
|
||||
$plaintext = substr($plaintext, self::BLOCK_SIZE);
|
||||
$contentLength = (unpack('N', substr($plaintext, 0, 4)) ?: [])[1];
|
||||
|
||||
if ($this->receiveId && trim(substr($plaintext, $contentLength + 4)) !== $this->receiveId) {
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadMethodCallException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadMethodCallException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadRequestException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadRequestException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadResponseException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/BadResponseException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/DecryptException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/DecryptException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/Exception.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/Exception.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/Exceptions/HttpException.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/Exceptions/HttpException.php
vendored
Executable file → Normal file
@ -12,12 +12,8 @@ class HttpException extends Exception
|
||||
|
||||
/**
|
||||
* HttpException constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param ResponseInterface|null $response
|
||||
* @param int $code
|
||||
*/
|
||||
public function __construct(string $message, ResponseInterface $response = null, int $code = 0)
|
||||
public function __construct(string $message, ?ResponseInterface $response = null, int $code = 0)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/InvalidArgumentException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/InvalidArgumentException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/InvalidConfigException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/InvalidConfigException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/RuntimeException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/RuntimeException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/ServiceNotFoundException.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Exceptions/ServiceNotFoundException.php
vendored
Executable file → Normal file
46
vendor/w7corp/easywechat/src/Kernel/Form/File.php
vendored
Executable file → Normal file
46
vendor/w7corp/easywechat/src/Kernel/Form/File.php
vendored
Executable file → Normal file
@ -2,30 +2,48 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Form;
|
||||
|
||||
use const PATHINFO_EXTENSION;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
|
||||
use function file_put_contents;
|
||||
use function md5;
|
||||
use function pathinfo;
|
||||
use const PATHINFO_EXTENSION;
|
||||
use function strtolower;
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use function sys_get_temp_dir;
|
||||
use function tempnam;
|
||||
|
||||
class File extends DataPart
|
||||
{
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
|
||||
*/
|
||||
public static function withContents(
|
||||
public static function from(
|
||||
string $pathOrContents,
|
||||
?string $filename = null,
|
||||
?string $contentType = null,
|
||||
?string $encoding = null
|
||||
): DataPart {
|
||||
if (file_exists($pathOrContents)) {
|
||||
return static::fromPath($pathOrContents, $filename, $contentType);
|
||||
}
|
||||
|
||||
return static::fromContents($pathOrContents, $filename, $contentType, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
|
||||
*/
|
||||
public static function fromContents(
|
||||
string $contents,
|
||||
?string $filename = null,
|
||||
?string $contentType = null,
|
||||
?string $encoding = null
|
||||
): DataPart {
|
||||
if (null === $contentType) {
|
||||
$mimeTypes = new MimeTypes();
|
||||
if ($contentType === null) {
|
||||
$mimeTypes = new MimeTypes;
|
||||
|
||||
if ($filename) {
|
||||
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
@ -44,4 +62,18 @@ class File extends DataPart
|
||||
|
||||
return new self($contents, $filename, $contentType, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @deprecated since EasyWeChat 7.0, use fromContents() instead
|
||||
*/
|
||||
public static function withContents(
|
||||
string $contents,
|
||||
?string $filename = null,
|
||||
?string $contentType = null,
|
||||
?string $encoding = null
|
||||
): DataPart {
|
||||
return self::fromContents($contents, $filename, $contentType, $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/w7corp/easywechat/src/Kernel/Form/Form.php
vendored
Executable file → Normal file
4
vendor/w7corp/easywechat/src/Kernel/Form/Form.php
vendored
Executable file → Normal file
@ -24,7 +24,7 @@ class Form
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
* @return array{headers:array<string,string|string[]>,body:string}
|
||||
*/
|
||||
#[ArrayShape(['headers' => 'array', 'body' => 'string'])]
|
||||
public function toArray(): array
|
||||
@ -33,7 +33,7 @@ class Form
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>
|
||||
* @return array{headers:array<string,string|string[]>,body:string}
|
||||
*/
|
||||
#[ArrayShape(['headers' => 'array', 'body' => 'string'])]
|
||||
public function toOptions(): array
|
||||
|
||||
6
vendor/w7corp/easywechat/src/Kernel/HttpClient/AccessTokenAwareClient.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/HttpClient/AccessTokenAwareClient.php
vendored
Executable file → Normal file
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\HttpClient;
|
||||
|
||||
use function array_merge;
|
||||
use Closure;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\AccessTokenAwareHttpClient as AccessTokenAwareHttpClientInterface;
|
||||
@ -15,19 +14,22 @@ use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function array_merge;
|
||||
|
||||
/**
|
||||
* Class AccessTokenAwareClient.
|
||||
*
|
||||
*
|
||||
* @method HttpClientInterface withAppIdAs(string $name = null) 自定义 app_id 参数名
|
||||
* @method HttpClientInterface withAppId(string $value = null)
|
||||
*/
|
||||
class AccessTokenAwareClient implements AccessTokenAwareHttpClientInterface
|
||||
{
|
||||
use AsyncDecoratorTrait;
|
||||
use HttpClientMethods;
|
||||
use RetryableClient;
|
||||
use MockableHttpClient;
|
||||
use RequestWithPresets;
|
||||
use RetryableClient;
|
||||
|
||||
public function __construct(
|
||||
?HttpClientInterface $client = null,
|
||||
|
||||
6
vendor/w7corp/easywechat/src/Kernel/HttpClient/AccessTokenExpiredRetryStrategy.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/HttpClient/AccessTokenExpiredRetryStrategy.php
vendored
Executable file → Normal file
@ -15,14 +15,14 @@ class AccessTokenExpiredRetryStrategy extends GenericRetryStrategy
|
||||
|
||||
protected ?Closure $decider = null;
|
||||
|
||||
public function withAccessToken(AccessTokenInterface $accessToken): self
|
||||
public function withAccessToken(AccessTokenInterface $accessToken): static
|
||||
{
|
||||
$this->accessToken = $accessToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function decideUsing(Closure $decider): self
|
||||
public function decideUsing(Closure $decider): static
|
||||
{
|
||||
$this->decider = $decider;
|
||||
|
||||
@ -34,7 +34,7 @@ class AccessTokenExpiredRetryStrategy extends GenericRetryStrategy
|
||||
?string $responseContent,
|
||||
?TransportExceptionInterface $exception
|
||||
): ?bool {
|
||||
if ((bool) $responseContent && $this->decider && ($this->decider)($context, $responseContent, $exception)) {
|
||||
if ($responseContent && $this->decider && ($this->decider)($context, $responseContent, $exception)) {
|
||||
if ($this->accessToken instanceof RefreshableAccessTokenInterface) {
|
||||
return (bool) $this->accessToken->refresh();
|
||||
}
|
||||
|
||||
14
vendor/w7corp/easywechat/src/Kernel/HttpClient/HttpClientMethods.php
vendored
Executable file → Normal file
14
vendor/w7corp/easywechat/src/Kernel/HttpClient/HttpClientMethods.php
vendored
Executable file → Normal file
@ -8,9 +8,7 @@ use Symfony\Contracts\HttpClient\ResponseInterface as ResponseInterfaceAlias;
|
||||
trait HttpClientMethods
|
||||
{
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array<string, mixed> $options
|
||||
* @return Response|ResponseInterfaceAlias
|
||||
*
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
@ -32,20 +30,28 @@ trait HttpClientMethods
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function postJson(string $url, array $options = []): Response|ResponseInterfaceAlias
|
||||
public function postJson(string $url, array $data = [], array $options = []): Response|ResponseInterfaceAlias
|
||||
{
|
||||
$options['headers']['Content-Type'] = 'application/json';
|
||||
|
||||
$options['json'] = $data;
|
||||
|
||||
return $this->request('POST', $url, RequestUtil::formatOptions($options, 'POST'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function postXml(string $url, array $options = []): Response|ResponseInterfaceAlias
|
||||
public function postXml(string $url, array $data = [], array $options = []): Response|ResponseInterfaceAlias
|
||||
{
|
||||
$options['headers']['Content-Type'] = 'text/xml';
|
||||
|
||||
if (array_key_exists('xml', $data)) {
|
||||
$data = $data['xml'];
|
||||
}
|
||||
|
||||
$options['xml'] = $data;
|
||||
|
||||
return $this->request('POST', $url, RequestUtil::formatOptions($options, 'POST'));
|
||||
}
|
||||
|
||||
|
||||
51
vendor/w7corp/easywechat/src/Kernel/HttpClient/RequestUtil.php
vendored
Executable file → Normal file
51
vendor/w7corp/easywechat/src/Kernel/HttpClient/RequestUtil.php
vendored
Executable file → Normal file
@ -3,23 +3,25 @@
|
||||
namespace EasyWeChat\Kernel\HttpClient;
|
||||
|
||||
use const ARRAY_FILTER_USE_KEY;
|
||||
use function array_key_exists;
|
||||
use EasyWeChat\Kernel\Support\UserAgent;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use function in_array;
|
||||
use InvalidArgumentException;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use function json_encode;
|
||||
use const JSON_FORCE_OBJECT;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
use EasyWeChat\Kernel\Support\UserAgent;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use InvalidArgumentException;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Symfony\Component\HttpClient\Retry\GenericRetryStrategy;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
|
||||
class RequestUtil
|
||||
{
|
||||
/**
|
||||
@ -80,12 +82,17 @@ class RequestUtil
|
||||
return $options;
|
||||
}
|
||||
|
||||
$contentType = $options['headers']['Content-Type'] ?? $options['headers']['content-type'] ?? null;
|
||||
$name = in_array($method, ['GET', 'HEAD', 'DELETE']) ? 'query' : 'body';
|
||||
|
||||
if (($options['headers']['Content-Type'] ?? $options['headers']['content-type'] ?? null) === 'application/json') {
|
||||
if ($contentType === 'application/json') {
|
||||
$name = 'json';
|
||||
}
|
||||
|
||||
if ($contentType === 'text/xml') {
|
||||
$name = 'xml';
|
||||
}
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
if (! array_key_exists($key, HttpClientInterface::OPTIONS_DEFAULTS)) {
|
||||
$options[$name][trim($key, '"')] = $value;
|
||||
@ -97,12 +104,14 @@ class RequestUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, array<string,mixed>|mixed> $options
|
||||
* @return array<string, array|mixed>
|
||||
* @param array{headers?:array<string, string>, xml?:mixed, body?:array|string, json?:mixed} $options
|
||||
* @return array{headers?:array<string, string|array<string, string>|array<string>>, xml?:array|string, body?:array|string}
|
||||
*/
|
||||
public static function formatBody(array $options): array
|
||||
{
|
||||
if (isset($options['xml'])) {
|
||||
$contentType = $options['headers']['Content-Type'] ?? $options['headers']['content-type'] ?? null;
|
||||
|
||||
if (array_key_exists('xml', $options)) {
|
||||
if (is_array($options['xml'])) {
|
||||
$options['xml'] = Xml::build($options['xml']);
|
||||
}
|
||||
@ -111,17 +120,15 @@ class RequestUtil
|
||||
throw new InvalidArgumentException('The type of `xml` must be string or array.');
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (! isset($options['headers']['Content-Type']) && ! isset($options['headers']['content-type'])) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$options['headers']['Content-Type'] = [$options['headers'][] = 'Content-Type: text/xml'];
|
||||
if (! $contentType) {
|
||||
$options['headers']['Content-Type'] = 'text/xml';
|
||||
}
|
||||
|
||||
$options['body'] = $options['xml'];
|
||||
unset($options['xml']);
|
||||
}
|
||||
|
||||
if (isset($options['json'])) {
|
||||
if (array_key_exists('json', $options)) {
|
||||
if (is_array($options['json'])) {
|
||||
/** XXX: 微信的 JSON 是比较奇葩的,比如菜单不能把中文 encode 为 unicode */
|
||||
$options['json'] = json_encode(
|
||||
@ -134,10 +141,8 @@ class RequestUtil
|
||||
throw new InvalidArgumentException('The type of `json` must be string or array.');
|
||||
}
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (! isset($options['headers']['Content-Type']) && ! isset($options['headers']['content-type'])) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$options['headers']['Content-Type'] = [$options['headers'][] = 'Content-Type: application/json'];
|
||||
if (! $contentType) {
|
||||
$options['headers']['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
$options['body'] = $options['json'];
|
||||
@ -149,7 +154,7 @@ class RequestUtil
|
||||
|
||||
public static function createDefaultServerRequest(): ServerRequestInterface
|
||||
{
|
||||
$psr17Factory = new Psr17Factory();
|
||||
$psr17Factory = new Psr17Factory;
|
||||
|
||||
$creator = new ServerRequestCreator(
|
||||
serverRequestFactory: $psr17Factory,
|
||||
|
||||
17
vendor/w7corp/easywechat/src/Kernel/HttpClient/RequestWithPresets.php
vendored
Executable file → Normal file
17
vendor/w7corp/easywechat/src/Kernel/HttpClient/RequestWithPresets.php
vendored
Executable file → Normal file
@ -2,12 +2,13 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\HttpClient;
|
||||
|
||||
use function array_merge;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\Kernel\Form\File;
|
||||
use EasyWeChat\Kernel\Form\Form;
|
||||
use EasyWeChat\Kernel\Support\Str;
|
||||
|
||||
use function array_merge;
|
||||
use function in_array;
|
||||
use function is_file;
|
||||
use function is_string;
|
||||
@ -85,17 +86,16 @@ trait RequestWithPresets
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function withFile(string $pathOrContents, string $formName = 'file', string $filename = null): static
|
||||
public function withFile(string $pathOrContents, string $formName = 'file', ?string $filename = null): static
|
||||
{
|
||||
$file = is_file($pathOrContents) ? File::fromPath(
|
||||
$pathOrContents,
|
||||
$filename
|
||||
) : File::withContents($pathOrContents, $filename);
|
||||
) : File::fromContents($pathOrContents, $filename);
|
||||
|
||||
/**
|
||||
* @var array{headers: array<string, string>, body: string}
|
||||
* @var array{headers: array<string, string>, body: string} $options
|
||||
*/
|
||||
$options = Form::create([$formName => $file])->toOptions();
|
||||
|
||||
@ -108,16 +108,14 @@ trait RequestWithPresets
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function withFileContents(string $contents, string $formName = 'file', string $filename = null): static
|
||||
public function withFileContents(string $contents, string $formName = 'file', ?string $filename = null): static
|
||||
{
|
||||
return $this->withFile($contents, $formName, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function withFiles(array $files): static
|
||||
{
|
||||
@ -128,6 +126,9 @@ trait RequestWithPresets
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{xml?:array<string,mixed>|string,json?:array<string,mixed>|string,body?:array<string,mixed>|string,query?:array<string,mixed>,headers?:array<string,string>}
|
||||
*/
|
||||
public function mergeThenResetPrepends(array $options, string $method = 'GET'): array
|
||||
{
|
||||
$name = in_array(strtoupper($method), ['GET', 'HEAD', 'DELETE']) ? 'query' : 'body';
|
||||
|
||||
34
vendor/w7corp/easywechat/src/Kernel/HttpClient/Response.php
vendored
Executable file → Normal file
34
vendor/w7corp/easywechat/src/Kernel/HttpClient/Response.php
vendored
Executable file → Normal file
@ -2,27 +2,20 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\HttpClient;
|
||||
|
||||
use function array_key_exists;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
use ArrayAccess;
|
||||
use function base64_encode;
|
||||
use Closure;
|
||||
use EasyWeChat\Kernel\Contracts\Arrayable;
|
||||
use EasyWeChat\Kernel\Contracts\Jsonable;
|
||||
use EasyWeChat\Kernel\Exceptions\BadMethodCallException;
|
||||
use EasyWeChat\Kernel\Exceptions\BadResponseException;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use function file_put_contents;
|
||||
use Http\Discovery\Exception\NotFoundException;
|
||||
use Http\Discovery\Psr17FactoryDiscovery;
|
||||
use function json_encode;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||
use Psr\Http\Message\ResponseFactoryInterface;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
use function sprintf;
|
||||
use function str_contains;
|
||||
use function str_starts_with;
|
||||
use function strtolower;
|
||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||
use Symfony\Component\HttpClient\Response\StreamableInterface;
|
||||
use Symfony\Component\HttpClient\Response\StreamWrapper;
|
||||
@ -34,12 +27,21 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
use Throwable;
|
||||
|
||||
use function array_key_exists;
|
||||
use function base64_encode;
|
||||
use function file_put_contents;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
use function str_contains;
|
||||
use function str_starts_with;
|
||||
use function strtolower;
|
||||
|
||||
/**
|
||||
* @implements \ArrayAccess<array-key, mixed>
|
||||
*
|
||||
* @see \Symfony\Contracts\HttpClient\ResponseInterface
|
||||
*/
|
||||
class Response implements Jsonable, Arrayable, ArrayAccess, ResponseInterface, StreamableInterface
|
||||
class Response implements Arrayable, ArrayAccess, Jsonable, ResponseInterface, StreamableInterface
|
||||
{
|
||||
public function __construct(
|
||||
protected ResponseInterface $response,
|
||||
@ -96,7 +98,7 @@ class Response implements Jsonable, Arrayable, ArrayAccess, ResponseInterface, S
|
||||
}
|
||||
|
||||
try {
|
||||
return 400 <= $this->getStatusCode();
|
||||
return $this->getStatusCode() >= 400;
|
||||
} catch (Throwable $e) {
|
||||
return true;
|
||||
}
|
||||
@ -159,7 +161,7 @@ class Response implements Jsonable, Arrayable, ArrayAccess, ResponseInterface, S
|
||||
throw new BadMethodCallException(sprintf('%s does\'t implements %s', \get_class($this->response), StreamableInterface::class));
|
||||
}
|
||||
|
||||
return StreamWrapper::createResource(new MockResponse());
|
||||
return StreamWrapper::createResource(new MockResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,17 +175,17 @@ class Response implements Jsonable, Arrayable, ArrayAccess, ResponseInterface, S
|
||||
return 'data:'.$this->getHeaderLine('content-type').';base64,'.base64_encode($this->getContent());
|
||||
}
|
||||
|
||||
public function toPsrResponse(ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null): \Psr\Http\Message\ResponseInterface
|
||||
public function toPsrResponse(?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null): \Psr\Http\Message\ResponseInterface
|
||||
{
|
||||
$streamFactory ??= $responseFactory instanceof StreamFactoryInterface ? $responseFactory : null;
|
||||
|
||||
if (null === $responseFactory || null === $streamFactory) {
|
||||
if ($responseFactory === null || $streamFactory === null) {
|
||||
if (! class_exists(Psr17Factory::class) && ! class_exists(Psr17FactoryDiscovery::class)) {
|
||||
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".');
|
||||
}
|
||||
|
||||
try {
|
||||
$psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null;
|
||||
$psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory : null;
|
||||
$responseFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); /** @phpstan-ignore-line */
|
||||
$streamFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); /** @phpstan-ignore-line */
|
||||
|
||||
@ -303,7 +305,7 @@ class Response implements Jsonable, Arrayable, ArrayAccess, ResponseInterface, S
|
||||
$this->response->cancel();
|
||||
}
|
||||
|
||||
public function getInfo(string $type = null): mixed
|
||||
public function getInfo(?string $type = null): mixed
|
||||
{
|
||||
return $this->response->getInfo($type);
|
||||
}
|
||||
|
||||
2
vendor/w7corp/easywechat/src/Kernel/HttpClient/RetryableClient.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/Kernel/HttpClient/RetryableClient.php
vendored
Executable file → Normal file
@ -36,7 +36,7 @@ trait RetryableClient
|
||||
public function retryUsing(
|
||||
RetryStrategyInterface $strategy,
|
||||
int $maxRetries = 3,
|
||||
LoggerInterface $logger = null
|
||||
?LoggerInterface $logger = null
|
||||
): static {
|
||||
$this->client = new RetryableHttpClient($this->client, $strategy, $maxRetries, $logger);
|
||||
|
||||
|
||||
62
vendor/w7corp/easywechat/src/Kernel/HttpClient/ScopingHttpClient.php
vendored
Normal file
62
vendor/w7corp/easywechat/src/Kernel/HttpClient/ScopingHttpClient.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\HttpClient;
|
||||
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\HttpClientTrait;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
class ScopingHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface
|
||||
{
|
||||
use HttpClientTrait;
|
||||
|
||||
private HttpClientInterface $client;
|
||||
|
||||
private array $defaultOptionsByRegexp;
|
||||
|
||||
public function __construct(HttpClientInterface $client, array $defaultOptionsByRegexp)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->defaultOptionsByRegexp = $defaultOptionsByRegexp;
|
||||
}
|
||||
|
||||
public function request(string $method, string $url, array $options = []): ResponseInterface
|
||||
{
|
||||
foreach ($this->defaultOptionsByRegexp as $regexp => $defaultOptions) {
|
||||
if (preg_match($regexp, $url)) {
|
||||
$options = self::mergeDefaultOptions($options, $defaultOptions, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->client->request($method, $url, $options);
|
||||
}
|
||||
|
||||
public function stream(ResponseInterface|iterable $responses, ?float $timeout = null): ResponseStreamInterface
|
||||
{
|
||||
return $this->client->stream($responses, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->client instanceof ResetInterface) {
|
||||
$this->client->reset();
|
||||
}
|
||||
}
|
||||
|
||||
public function setLogger(LoggerInterface $logger): void
|
||||
{
|
||||
if ($this->client instanceof LoggerAwareInterface) {
|
||||
$this->client->setLogger($logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
vendor/w7corp/easywechat/src/Kernel/Message.php
vendored
Executable file → Normal file
11
vendor/w7corp/easywechat/src/Kernel/Message.php
vendored
Executable file → Normal file
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace EasyWeChat\Kernel;
|
||||
|
||||
use ArrayAccess;
|
||||
use EasyWeChat\Kernel\Contracts\Jsonable;
|
||||
use EasyWeChat\Kernel\Exceptions\BadRequestException;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use EasyWeChat\Kernel\Traits\HasAttributes;
|
||||
@ -14,9 +15,10 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
* @property string $FromUserName
|
||||
* @property string $ToUserName
|
||||
* @property string $Encrypt
|
||||
*
|
||||
* @implements ArrayAccess<array-key, mixed>
|
||||
*/
|
||||
abstract class Message implements ArrayAccess
|
||||
abstract class Message implements \JsonSerializable, ArrayAccess, Jsonable
|
||||
{
|
||||
use HasAttributes;
|
||||
|
||||
@ -29,9 +31,6 @@ abstract class Message implements ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return Message
|
||||
*
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public static function createFromRequest(ServerRequestInterface $request): Message
|
||||
@ -48,14 +47,14 @@ abstract class Message implements ArrayAccess
|
||||
*/
|
||||
public static function format(string $originContent): array
|
||||
{
|
||||
if (0 === stripos($originContent, '<')) {
|
||||
if (stripos($originContent, '<') === 0) {
|
||||
$attributes = Xml::parse($originContent);
|
||||
}
|
||||
|
||||
// Handle JSON format.
|
||||
$dataSet = json_decode($originContent, true);
|
||||
|
||||
if (JSON_ERROR_NONE === json_last_error() && $originContent) {
|
||||
if (json_last_error() === JSON_ERROR_NONE && $originContent) {
|
||||
$attributes = $dataSet;
|
||||
}
|
||||
|
||||
|
||||
35
vendor/w7corp/easywechat/src/Kernel/ServerResponse.php
vendored
Executable file → Normal file
35
vendor/w7corp/easywechat/src/Kernel/ServerResponse.php
vendored
Executable file → Normal file
@ -2,17 +2,18 @@
|
||||
|
||||
namespace EasyWeChat\Kernel;
|
||||
|
||||
use const PHP_OUTPUT_HANDLER_CLEANABLE;
|
||||
use const PHP_OUTPUT_HANDLER_FLUSHABLE;
|
||||
use const PHP_OUTPUT_HANDLER_REMOVABLE;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function header;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use function max;
|
||||
use const PHP_OUTPUT_HANDLER_CLEANABLE;
|
||||
use const PHP_OUTPUT_HANDLER_FLUSHABLE;
|
||||
use const PHP_OUTPUT_HANDLER_REMOVABLE;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use function sprintf;
|
||||
use function ucwords;
|
||||
|
||||
@ -23,7 +24,6 @@ class ServerResponse implements ResponseInterface
|
||||
$this->response->getBody()->rewind();
|
||||
}
|
||||
|
||||
#[Pure]
|
||||
public static function make(ResponseInterface $response): ServerResponse
|
||||
{
|
||||
if ($response instanceof ServerResponse) {
|
||||
@ -132,7 +132,7 @@ class ServerResponse implements ResponseInterface
|
||||
}
|
||||
|
||||
foreach ($this->getHeaders() as $name => $values) {
|
||||
$replace = 0 === \strcasecmp($name, 'Content-Type');
|
||||
$replace = \strcasecmp($name, 'Content-Type') === 0;
|
||||
|
||||
foreach ($values as $value) {
|
||||
header($name.': '.$value, $replace, $this->getStatusCode());
|
||||
@ -166,6 +166,7 @@ class ServerResponse implements ResponseInterface
|
||||
* Resulting level can be greater than target level if a non-removable buffer has been encountered.
|
||||
*
|
||||
* @link https://github.com/symfony/http-foundation/blob/6.1/Response.php
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public static function closeOutputBuffers(int $targetLevel, bool $flush): void
|
||||
@ -186,16 +187,18 @@ class ServerResponse implements ResponseInterface
|
||||
public function __toString(): string
|
||||
{
|
||||
$headers = $this->getHeaders();
|
||||
|
||||
ksort($headers);
|
||||
|
||||
$max = max(array_map('strlen', array_keys($headers))) + 1;
|
||||
$headersString = '';
|
||||
|
||||
foreach ($headers as $name => $values) {
|
||||
$name = ucwords($name, '-');
|
||||
foreach ($values as $value) {
|
||||
$headersString .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
|
||||
if (! empty($headers)) {
|
||||
ksort($headers);
|
||||
|
||||
$max = max(array_map('strlen', array_keys($headers))) + 1;
|
||||
|
||||
foreach ($headers as $name => $values) {
|
||||
$name = ucwords($name, '-');
|
||||
foreach ($values as $value) {
|
||||
$headersString .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
vendor/w7corp/easywechat/src/Kernel/Support/AesCbc.php
vendored
Executable file → Normal file
14
vendor/w7corp/easywechat/src/Kernel/Support/AesCbc.php
vendored
Executable file → Normal file
@ -2,23 +2,25 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use function base64_decode;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\Aes;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
|
||||
use function base64_decode;
|
||||
use function openssl_decrypt;
|
||||
use function openssl_error_string;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
class AesCbc implements Aes
|
||||
{
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function encrypt(string $plaintext, string $key, string $iv = null): string
|
||||
public static function encrypt(string $plaintext, string $key, ?string $iv = null): string
|
||||
{
|
||||
$ciphertext = \openssl_encrypt($plaintext, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, (string) $iv);
|
||||
|
||||
if (false === $ciphertext) {
|
||||
if ($ciphertext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Encrypt AES CBC error.');
|
||||
}
|
||||
|
||||
@ -28,7 +30,7 @@ class AesCbc implements Aes
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function decrypt(string $ciphertext, string $key, string $iv = null): string
|
||||
public static function decrypt(string $ciphertext, string $key, ?string $iv = null): string
|
||||
{
|
||||
$plaintext = openssl_decrypt(
|
||||
base64_decode($ciphertext),
|
||||
@ -38,7 +40,7 @@ class AesCbc implements Aes
|
||||
(string) $iv
|
||||
);
|
||||
|
||||
if (false === $plaintext) {
|
||||
if ($plaintext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Decrypt AES CBC error.');
|
||||
}
|
||||
|
||||
|
||||
14
vendor/w7corp/easywechat/src/Kernel/Support/AesEcb.php
vendored
Executable file → Normal file
14
vendor/w7corp/easywechat/src/Kernel/Support/AesEcb.php
vendored
Executable file → Normal file
@ -2,23 +2,25 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use function base64_decode;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\Aes;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
|
||||
use function base64_decode;
|
||||
use function openssl_decrypt;
|
||||
use function openssl_error_string;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
class AesEcb implements Aes
|
||||
{
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function encrypt(string $plaintext, string $key, string $iv = null): string
|
||||
public static function encrypt(string $plaintext, string $key, ?string $iv = null): string
|
||||
{
|
||||
$ciphertext = \openssl_encrypt($plaintext, 'aes-256-ecb', $key, OPENSSL_RAW_DATA, (string) $iv);
|
||||
|
||||
if (false === $ciphertext) {
|
||||
if ($ciphertext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Encrypt AES ECB failed.');
|
||||
}
|
||||
|
||||
@ -28,7 +30,7 @@ class AesEcb implements Aes
|
||||
/**
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function decrypt(string $ciphertext, string $key, string $iv = null): string
|
||||
public static function decrypt(string $ciphertext, string $key, ?string $iv = null): string
|
||||
{
|
||||
$plaintext = openssl_decrypt(
|
||||
base64_decode($ciphertext, true) ?: '',
|
||||
@ -38,7 +40,7 @@ class AesEcb implements Aes
|
||||
(string) $iv
|
||||
);
|
||||
|
||||
if (false === $plaintext) {
|
||||
if ($plaintext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Decrypt AES ECB failed.');
|
||||
}
|
||||
|
||||
|
||||
16
vendor/w7corp/easywechat/src/Kernel/Support/AesGcm.php
vendored
Executable file → Normal file
16
vendor/w7corp/easywechat/src/Kernel/Support/AesGcm.php
vendored
Executable file → Normal file
@ -2,14 +2,16 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use function base64_decode;
|
||||
use function base64_encode;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\Aes;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
|
||||
use function base64_decode;
|
||||
use function base64_encode;
|
||||
use function openssl_decrypt;
|
||||
use function openssl_encrypt;
|
||||
use function openssl_error_string;
|
||||
use const OPENSSL_RAW_DATA;
|
||||
|
||||
class AesGcm implements Aes
|
||||
{
|
||||
@ -18,7 +20,7 @@ class AesGcm implements Aes
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function encrypt(string $plaintext, string $key, string $iv = null, string $aad = ''): string
|
||||
public static function encrypt(string $plaintext, string $key, ?string $iv = null, string $aad = ''): string
|
||||
{
|
||||
$ciphertext = openssl_encrypt(
|
||||
$plaintext,
|
||||
@ -31,7 +33,7 @@ class AesGcm implements Aes
|
||||
self::BLOCK_SIZE
|
||||
);
|
||||
|
||||
if (false === $ciphertext) {
|
||||
if ($ciphertext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Encrypt failed');
|
||||
}
|
||||
|
||||
@ -41,7 +43,7 @@ class AesGcm implements Aes
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function decrypt(string $ciphertext, string $key, string $iv = null, string $aad = ''): string
|
||||
public static function decrypt(string $ciphertext, string $key, ?string $iv = null, string $aad = ''): string
|
||||
{
|
||||
$ciphertext = base64_decode($ciphertext);
|
||||
|
||||
@ -51,7 +53,7 @@ class AesGcm implements Aes
|
||||
|
||||
$plaintext = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, (string) $iv, $tag, $aad);
|
||||
|
||||
if (false === $plaintext) {
|
||||
if ($plaintext === false) {
|
||||
throw new InvalidArgumentException(openssl_error_string() ?: 'Decrypt failed');
|
||||
}
|
||||
|
||||
|
||||
29
vendor/w7corp/easywechat/src/Kernel/Support/Arr.php
vendored
Executable file → Normal file
29
vendor/w7corp/easywechat/src/Kernel/Support/Arr.php
vendored
Executable file → Normal file
@ -4,20 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use function is_string;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
|
||||
use function is_string;
|
||||
|
||||
class Arr
|
||||
{
|
||||
/**
|
||||
* @param array<string|int, mixed> $array
|
||||
* @param string|int|null $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
#[Pure]
|
||||
public static function get(array $array, string|int|null $key, mixed $default = null): mixed
|
||||
public static function get(mixed $array, string|int|null $key, mixed $default = null): mixed
|
||||
{
|
||||
if (! is_array($array)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_null($key)) {
|
||||
return $array;
|
||||
}
|
||||
@ -27,9 +26,7 @@ class Arr
|
||||
}
|
||||
|
||||
foreach (explode('.', (string) $key) as $segment) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (static::exists($array, $segment)) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (is_array($array) && static::exists($array, $segment)) {
|
||||
$array = $array[$segment];
|
||||
} else {
|
||||
return $default;
|
||||
@ -41,8 +38,6 @@ class Arr
|
||||
|
||||
/**
|
||||
* @param array<int|string, mixed> $array
|
||||
* @param string|int $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists(array $array, string|int $key): bool
|
||||
{
|
||||
@ -51,9 +46,7 @@ class Arr
|
||||
|
||||
/**
|
||||
* @param array<string|int, mixed> $array
|
||||
* @param string|int|null $key
|
||||
* @param mixed $value
|
||||
* @return array<string|int, mixed>
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function set(array &$array, string|int|null $key, mixed $value): array
|
||||
{
|
||||
@ -83,7 +76,6 @@ class Arr
|
||||
|
||||
/**
|
||||
* @param array<string|int, mixed> $array
|
||||
* @param string $prepend
|
||||
* @return array<string|int, mixed>
|
||||
*/
|
||||
public static function dot(array $array, string $prepend = ''): array
|
||||
@ -104,7 +96,6 @@ class Arr
|
||||
/**
|
||||
* @param array<string|int, mixed> $array
|
||||
* @param string|int|array<string|int, mixed>|null $keys
|
||||
* @return bool
|
||||
*/
|
||||
#[Pure]
|
||||
public static function has(array $array, string|int|array|null $keys): bool
|
||||
@ -119,7 +110,7 @@ class Arr
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([] === $keys) {
|
||||
if ($keys === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
4
vendor/w7corp/easywechat/src/Kernel/Support/Pkcs7.php
vendored
Executable file → Normal file
4
vendor/w7corp/easywechat/src/Kernel/Support/Pkcs7.php
vendored
Executable file → Normal file
@ -11,8 +11,8 @@ class Pkcs7
|
||||
*/
|
||||
public static function padding(string $contents, int $blockSize): string
|
||||
{
|
||||
if ($blockSize > 256) {
|
||||
throw new InvalidArgumentException('$blockSize may not be more than 256');
|
||||
if ($blockSize > 32) {
|
||||
throw new InvalidArgumentException('$blockSize may not be more than 32 bytes(256 bits)');
|
||||
}
|
||||
$padding = $blockSize - (strlen($contents) % $blockSize);
|
||||
$pattern = chr($padding);
|
||||
|
||||
3
vendor/w7corp/easywechat/src/Kernel/Support/PrivateKey.php
vendored
Executable file → Normal file
3
vendor/w7corp/easywechat/src/Kernel/Support/PrivateKey.php
vendored
Executable file → Normal file
@ -2,9 +2,10 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use function str_starts_with;
|
||||
|
||||
class PrivateKey
|
||||
|
||||
5
vendor/w7corp/easywechat/src/Kernel/Support/PublicKey.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/Kernel/Support/PublicKey.php
vendored
Executable file → Normal file
@ -3,6 +3,7 @@
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
|
||||
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function openssl_x509_parse;
|
||||
@ -25,11 +26,11 @@ class PublicKey
|
||||
{
|
||||
$info = openssl_x509_parse($this->certificate);
|
||||
|
||||
if (false === $info || ! isset($info['serialNumberHex'])) {
|
||||
if ($info === false) {
|
||||
throw new InvalidConfigException('Read the $certificate failed, please check it whether or nor correct');
|
||||
}
|
||||
|
||||
return strtoupper($info['serialNumberHex'] ?? '');
|
||||
return strtoupper($info['serialNumberHex']);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
|
||||
3
vendor/w7corp/easywechat/src/Kernel/Support/Str.php
vendored
Executable file → Normal file
3
vendor/w7corp/easywechat/src/Kernel/Support/Str.php
vendored
Executable file → Normal file
@ -2,8 +2,9 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use function base64_encode;
|
||||
use Exception;
|
||||
|
||||
use function base64_encode;
|
||||
use function preg_replace;
|
||||
use function random_bytes;
|
||||
use function str_replace;
|
||||
|
||||
7
vendor/w7corp/easywechat/src/Kernel/Support/UserAgent.php
vendored
Executable file → Normal file
7
vendor/w7corp/easywechat/src/Kernel/Support/UserAgent.php
vendored
Executable file → Normal file
@ -4,10 +4,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\Support;
|
||||
|
||||
use Composer\InstalledVersions;
|
||||
|
||||
use function array_map;
|
||||
use function array_unshift;
|
||||
use function class_exists;
|
||||
use Composer\InstalledVersions;
|
||||
use function constant;
|
||||
use function curl_version;
|
||||
use function defined;
|
||||
use function explode;
|
||||
@ -19,14 +21,13 @@ class UserAgent
|
||||
{
|
||||
/**
|
||||
* @param array<string> $appends
|
||||
* @return string
|
||||
*/
|
||||
public static function create(array $appends = []): string
|
||||
{
|
||||
$value = array_map('strval', $appends);
|
||||
|
||||
if (defined('HHVM_VERSION')) {
|
||||
array_unshift($value, 'HHVM/'.HHVM_VERSION);
|
||||
array_unshift($value, 'HHVM/'.constant('HHVM_VERSION'));
|
||||
}
|
||||
|
||||
$disabledFunctions = explode(',', ini_get('disable_functions') ?: '');
|
||||
|
||||
2
vendor/w7corp/easywechat/src/Kernel/Support/Xml.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/Kernel/Support/Xml.php
vendored
Executable file → Normal file
@ -8,7 +8,7 @@ use TheNorthMemory\Xml\Transformer;
|
||||
|
||||
class Xml
|
||||
{
|
||||
public static function parse(string $xml): array|null
|
||||
public static function parse(string $xml): ?array
|
||||
{
|
||||
return Transformer::toArray($xml);
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Traits/DecryptXmlMessage.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Traits/DecryptXmlMessage.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/Traits/HasAttributes.php
vendored
Executable file → Normal file
6
vendor/w7corp/easywechat/src/Kernel/Traits/HasAttributes.php
vendored
Executable file → Normal file
@ -11,7 +11,7 @@ use function json_encode;
|
||||
trait HasAttributes
|
||||
{
|
||||
/**
|
||||
* @var array<int|string,mixed>
|
||||
* @var array<int|string,mixed>
|
||||
*/
|
||||
protected array $attributes = [];
|
||||
|
||||
@ -52,7 +52,7 @@ trait HasAttributes
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int|string,mixed> $attributes
|
||||
* @return array<int|string,mixed> $attributes
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
@ -82,7 +82,7 @@ trait HasAttributes
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if (null === $offset) {
|
||||
if ($offset === null) {
|
||||
$this->attributes[] = $value;
|
||||
} else {
|
||||
$this->attributes[$offset] = $value;
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithCache.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithCache.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithClient.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithClient.php
vendored
Executable file → Normal file
1
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithConfig.php
vendored
Executable file → Normal file
1
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithConfig.php
vendored
Executable file → Normal file
@ -7,6 +7,7 @@ namespace EasyWeChat\Kernel\Traits;
|
||||
use EasyWeChat\Kernel\Config;
|
||||
use EasyWeChat\Kernel\Contracts\Config as ConfigInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
|
||||
use function is_array;
|
||||
|
||||
trait InteractWithConfig
|
||||
|
||||
20
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithHandlers.php
vendored
Executable file → Normal file
20
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithHandlers.php
vendored
Executable file → Normal file
@ -4,17 +4,18 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\Kernel\Traits;
|
||||
|
||||
use Closure;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
|
||||
use function array_reverse;
|
||||
use function array_unshift;
|
||||
use function call_user_func;
|
||||
use Closure;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use function func_get_args;
|
||||
use function gettype;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use function is_string;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use function method_exists;
|
||||
use function spl_object_hash;
|
||||
|
||||
@ -52,7 +53,6 @@ trait InteractWithHandlers
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|string $handler
|
||||
* @return array{hash: string, handler: callable}
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
@ -69,14 +69,15 @@ trait InteractWithHandlers
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function getHandlerHash(callable|string $handler): string
|
||||
protected function getHandlerHash(callable|array|string $handler): string
|
||||
{
|
||||
return match (true) {
|
||||
is_string($handler) => $handler,
|
||||
is_array($handler) => is_string($handler[0]) ? $handler[0].'::'.$handler[1] : get_class(
|
||||
$handler[0]
|
||||
).$handler[1],
|
||||
is_array($handler) => is_string($handler[0])
|
||||
? $handler[0].'::'.$handler[1]
|
||||
: get_class($handler[0]).$handler[1],
|
||||
$handler instanceof Closure => spl_object_hash($handler),
|
||||
is_callable($handler) => spl_object_hash($handler),
|
||||
default => throw new InvalidArgumentException('Invalid handler: '.gettype($handler)),
|
||||
};
|
||||
}
|
||||
@ -93,9 +94,10 @@ trait InteractWithHandlers
|
||||
if (class_exists($handler) && method_exists($handler, '__invoke')) {
|
||||
/**
|
||||
* @psalm-suppress InvalidFunctionCall
|
||||
*
|
||||
* @phpstan-ignore-next-line https://github.com/phpstan/phpstan/issues/5867
|
||||
*/
|
||||
return fn (): mixed => (new $handler())(...func_get_args());
|
||||
return fn (): mixed => (new $handler)(...func_get_args());
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Invalid handler: %s.', $handler));
|
||||
|
||||
22
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithHttpClient.php
vendored
Executable file → Normal file
22
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithHttpClient.php
vendored
Executable file → Normal file
@ -5,11 +5,15 @@ declare(strict_types=1);
|
||||
namespace EasyWeChat\Kernel\Traits;
|
||||
|
||||
use EasyWeChat\Kernel\HttpClient\RequestUtil;
|
||||
use function property_exists;
|
||||
use EasyWeChat\Kernel\HttpClient\ScopingHttpClient;
|
||||
use EasyWeChat\Kernel\Support\Arr;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function is_array;
|
||||
|
||||
trait InteractWithHttpClient
|
||||
{
|
||||
protected ?HttpClientInterface $httpClient = null;
|
||||
@ -28,8 +32,7 @@ trait InteractWithHttpClient
|
||||
$this->httpClient = $httpClient;
|
||||
|
||||
if ($this instanceof LoggerAwareInterface && $httpClient instanceof LoggerAwareInterface
|
||||
&& property_exists($this, 'logger')
|
||||
&& $this->logger) {
|
||||
&& $this->logger instanceof LoggerInterface) {
|
||||
$httpClient->setLogger($this->logger);
|
||||
}
|
||||
|
||||
@ -38,7 +41,18 @@ trait InteractWithHttpClient
|
||||
|
||||
protected function createHttpClient(): HttpClientInterface
|
||||
{
|
||||
return HttpClient::create(RequestUtil::formatDefaultOptions($this->getHttpClientDefaultOptions()));
|
||||
$options = $this->getHttpClientDefaultOptions();
|
||||
|
||||
$optionsByRegexp = Arr::get($options, 'options_by_regexp', []);
|
||||
unset($options['options_by_regexp']);
|
||||
|
||||
$client = HttpClient::create(RequestUtil::formatDefaultOptions($options));
|
||||
|
||||
if (is_array($optionsByRegexp) && ! empty($optionsByRegexp)) {
|
||||
$client = new ScopingHttpClient($client, $optionsByRegexp);
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithServerRequest.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/Kernel/Traits/InteractWithServerRequest.php
vendored
Executable file → Normal file
@ -32,7 +32,7 @@ trait InteractWithServerRequest
|
||||
|
||||
public function setRequestFromSymfonyRequest(Request $symfonyRequest): static
|
||||
{
|
||||
$psr17Factory = new Psr17Factory();
|
||||
$psr17Factory = new Psr17Factory;
|
||||
$psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
||||
|
||||
$this->request = $psrHttpFactory->createRequest($symfonyRequest);
|
||||
|
||||
0
vendor/w7corp/easywechat/src/Kernel/Traits/MockableHttpClient.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/Kernel/Traits/MockableHttpClient.php
vendored
Executable file → Normal file
10
vendor/w7corp/easywechat/src/Kernel/Traits/RespondXmlMessage.php
vendored
Executable file → Normal file
10
vendor/w7corp/easywechat/src/Kernel/Traits/RespondXmlMessage.php
vendored
Executable file → Normal file
@ -2,16 +2,18 @@
|
||||
|
||||
namespace EasyWeChat\Kernel\Traits;
|
||||
|
||||
use function array_merge;
|
||||
use EasyWeChat\Kernel\Encryptor;
|
||||
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\Kernel\Message;
|
||||
use EasyWeChat\Kernel\Support\Xml;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use Nyholm\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
use function array_merge;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use function is_string;
|
||||
use function time;
|
||||
|
||||
trait RespondXmlMessage
|
||||
@ -48,7 +50,7 @@ trait RespondXmlMessage
|
||||
*/
|
||||
protected function normalizeResponse(mixed $response): array
|
||||
{
|
||||
if (is_callable($response)) {
|
||||
if (! is_string($response) && is_callable($response)) {
|
||||
$response = $response();
|
||||
}
|
||||
|
||||
|
||||
2
vendor/w7corp/easywechat/src/MiniApp/AccessToken.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/MiniApp/AccessToken.php
vendored
Executable file → Normal file
@ -6,5 +6,5 @@ namespace EasyWeChat\MiniApp;
|
||||
|
||||
class AccessToken extends \EasyWeChat\OfficialAccount\AccessToken
|
||||
{
|
||||
//
|
||||
const CACHE_KEY_PREFIX = 'mini_app';
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/MiniApp/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Account.php
vendored
Executable file → Normal file
18
vendor/w7corp/easywechat/src/MiniApp/Application.php
vendored
Executable file → Normal file
18
vendor/w7corp/easywechat/src/MiniApp/Application.php
vendored
Executable file → Normal file
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\MiniApp;
|
||||
|
||||
use function array_merge;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\Server as ServerInterface;
|
||||
use EasyWeChat\Kernel\Encryptor;
|
||||
@ -20,23 +19,25 @@ use EasyWeChat\Kernel\Traits\InteractWithHttpClient;
|
||||
use EasyWeChat\Kernel\Traits\InteractWithServerRequest;
|
||||
use EasyWeChat\MiniApp\Contracts\Account as AccountInterface;
|
||||
use EasyWeChat\MiniApp\Contracts\Application as ApplicationInterface;
|
||||
use function is_null;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use function str_contains;
|
||||
use Symfony\Component\HttpClient\Response\AsyncContext;
|
||||
use Symfony\Component\HttpClient\RetryableHttpClient;
|
||||
|
||||
use function array_merge;
|
||||
use function is_null;
|
||||
use function str_contains;
|
||||
|
||||
/**
|
||||
* @psalm-suppress PropertyNotSetInConstructor
|
||||
*/
|
||||
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;
|
||||
@ -131,6 +132,7 @@ class Application implements ApplicationInterface
|
||||
secret: $this->getAccount()->getSecret(),
|
||||
cache: $this->getCache(),
|
||||
httpClient: $this->getHttpClient(),
|
||||
stable: $this->config->get('use_stable_access_token', false)
|
||||
);
|
||||
}
|
||||
|
||||
@ -154,7 +156,7 @@ class Application implements ApplicationInterface
|
||||
{
|
||||
$httpClient = $this->getHttpClient();
|
||||
|
||||
if ((bool) $this->config->get('http.retry', false)) {
|
||||
if ($this->config->get('http.retry', false)) {
|
||||
$httpClient = new RetryableHttpClient(
|
||||
$httpClient,
|
||||
$this->getRetryStrategy(),
|
||||
@ -167,7 +169,7 @@ class Application implements ApplicationInterface
|
||||
accessToken: $this->getAccessToken(),
|
||||
failureJudge: fn (
|
||||
Response $response
|
||||
) => (bool) ($response->toArray()['errcode'] ?? 0) || ! is_null($response->toArray()['error'] ?? null),
|
||||
) => ($response->toArray()['errcode'] ?? 0) || ! is_null($response->toArray()['error'] ?? null),
|
||||
throw: (bool) $this->config->get('http.throw', true),
|
||||
))->setPresets($this->config->all());
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/MiniApp/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Contracts/Application.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/MiniApp/Decryptor.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/MiniApp/Decryptor.php
vendored
Executable file → Normal file
@ -4,13 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\MiniApp;
|
||||
|
||||
use function base64_decode;
|
||||
use EasyWeChat\Kernel\Exceptions\DecryptException;
|
||||
use EasyWeChat\Kernel\Support\AesCbc;
|
||||
use Throwable;
|
||||
|
||||
use function base64_decode;
|
||||
use function is_array;
|
||||
use function json_decode;
|
||||
use function sprintf;
|
||||
use Throwable;
|
||||
|
||||
class Decryptor
|
||||
{
|
||||
|
||||
0
vendor/w7corp/easywechat/src/MiniApp/Server.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Server.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Utils.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/MiniApp/Utils.php
vendored
Executable file → Normal file
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
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenPlatform/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Account.php
vendored
Executable file → Normal file
15
vendor/w7corp/easywechat/src/OpenPlatform/Application.php
vendored
Executable file → Normal file
15
vendor/w7corp/easywechat/src/OpenPlatform/Application.php
vendored
Executable file → Normal file
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenPlatform;
|
||||
|
||||
use function array_merge;
|
||||
use Closure;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\Server as ServerInterface;
|
||||
@ -25,25 +24,29 @@ use EasyWeChat\OfficialAccount\Config as OfficialAccountConfig;
|
||||
use EasyWeChat\OpenPlatform\Contracts\Account as AccountInterface;
|
||||
use EasyWeChat\OpenPlatform\Contracts\Application as ApplicationInterface;
|
||||
use EasyWeChat\OpenPlatform\Contracts\VerifyTicket as VerifyTicketInterface;
|
||||
use function is_string;
|
||||
use function md5;
|
||||
use Overtrue\Socialite\Contracts\ProviderInterface as SocialiteProviderInterface;
|
||||
use Overtrue\Socialite\Providers\WeChat;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use function sprintf;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
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 array_merge;
|
||||
use function is_string;
|
||||
use function md5;
|
||||
use function sprintf;
|
||||
|
||||
class Application implements ApplicationInterface
|
||||
{
|
||||
use InteractWithCache;
|
||||
use InteractWithConfig;
|
||||
use InteractWithClient;
|
||||
use InteractWithConfig;
|
||||
use InteractWithHttpClient;
|
||||
use InteractWithServerRequest;
|
||||
use LoggerAwareTrait;
|
||||
|
||||
protected ?Encryptor $encryptor = null;
|
||||
|
||||
@ -368,7 +371,7 @@ class Application implements ApplicationInterface
|
||||
'token' => $this->config->get('token'),
|
||||
'aes_key' => $this->config->get('aes_key'),
|
||||
'logging' => $this->config->get('logging'),
|
||||
'http' => $this->config->get('http'),
|
||||
'http' => $this->config->get('http', []),
|
||||
],
|
||||
$config
|
||||
)
|
||||
|
||||
2
vendor/w7corp/easywechat/src/OpenPlatform/Authorization.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/OpenPlatform/Authorization.php
vendored
Executable file → Normal file
@ -13,7 +13,7 @@ use JetBrains\PhpStorm\Pure;
|
||||
/**
|
||||
* @implements ArrayAccess<string, mixed>
|
||||
*/
|
||||
class Authorization implements ArrayAccess, Jsonable, Arrayable
|
||||
class Authorization implements Arrayable, ArrayAccess, Jsonable
|
||||
{
|
||||
use HasAttributes;
|
||||
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenPlatform/AuthorizerAccessToken.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/AuthorizerAccessToken.php
vendored
Executable file → Normal file
9
vendor/w7corp/easywechat/src/OpenPlatform/ComponentAccessToken.php
vendored
Executable file → Normal file
9
vendor/w7corp/easywechat/src/OpenPlatform/ComponentAccessToken.php
vendored
Executable file → Normal file
@ -4,19 +4,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenPlatform;
|
||||
|
||||
use function abs;
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken as RefreshableAccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use EasyWeChat\OpenPlatform\Contracts\VerifyTicket as VerifyTicketInterface;
|
||||
use function intval;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use function json_encode;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function abs;
|
||||
use function intval;
|
||||
use function json_encode;
|
||||
|
||||
class ComponentAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
@ -60,7 +61,7 @@ class ComponentAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
$token = $this->cache->get($this->getKey());
|
||||
|
||||
if ((bool) $token && \is_string($token)) {
|
||||
if ($token && \is_string($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenPlatform/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/VerifyTicket.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Contracts/VerifyTicket.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Message.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenPlatform/Message.php
vendored
Executable file → Normal file
27
vendor/w7corp/easywechat/src/OpenPlatform/Server.php
vendored
Executable file → Normal file
27
vendor/w7corp/easywechat/src/OpenPlatform/Server.php
vendored
Executable file → Normal file
@ -10,34 +10,31 @@ 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 function func_get_args;
|
||||
use Nyholm\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
use function func_get_args;
|
||||
|
||||
class Server implements ServerInterface
|
||||
{
|
||||
use InteractWithHandlers;
|
||||
use RespondXmlMessage;
|
||||
use DecryptXmlMessage;
|
||||
use InteractWithHandlers;
|
||||
use InteractWithServerRequest;
|
||||
use RespondXmlMessage;
|
||||
|
||||
protected ?Closure $defaultVerifyTicketHandler = null;
|
||||
|
||||
protected ServerRequestInterface $request;
|
||||
|
||||
/**
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function __construct(
|
||||
protected Encryptor $encryptor,
|
||||
?ServerRequestInterface $request = null,
|
||||
) {
|
||||
$this->request = $request ?? RequestUtil::createDefaultServerRequest();
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,11 +44,11 @@ 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);
|
||||
$message = $this->getRequestMessage($this->getRequest());
|
||||
|
||||
$this->prepend($this->decryptRequestMessage());
|
||||
|
||||
@ -127,7 +124,7 @@ class Server implements ServerInterface
|
||||
|
||||
protected function decryptRequestMessage(): Closure
|
||||
{
|
||||
$query = $this->request->getQueryParams();
|
||||
$query = $this->getRequest()->getQueryParams();
|
||||
|
||||
return function (Message $message, Closure $next) use ($query): mixed {
|
||||
$message = $this->decryptMessage(
|
||||
@ -147,7 +144,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());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +153,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();
|
||||
|
||||
|
||||
5
vendor/w7corp/easywechat/src/OpenPlatform/VerifyTicket.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/OpenPlatform/VerifyTicket.php
vendored
Executable file → Normal file
@ -6,13 +6,14 @@ namespace EasyWeChat\OpenPlatform;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\OpenPlatform\Contracts\VerifyTicket as VerifyTicketInterface;
|
||||
use function is_string;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use function sprintf;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
class VerifyTicket implements VerifyTicketInterface
|
||||
{
|
||||
protected CacheInterface $cache;
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenWork/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Account.php
vendored
Executable file → Normal file
80
vendor/w7corp/easywechat/src/OpenWork/Application.php
vendored
Executable file → Normal file
80
vendor/w7corp/easywechat/src/OpenWork/Application.php
vendored
Executable file → Normal file
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenWork;
|
||||
|
||||
use function array_merge;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\Server as ServerInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
@ -20,14 +19,23 @@ use EasyWeChat\OpenWork\Contracts\Application as ApplicationInterface;
|
||||
use EasyWeChat\OpenWork\Contracts\SuiteTicket as SuiteTicketInterface;
|
||||
use Overtrue\Socialite\Contracts\ProviderInterface as SocialiteProviderInterface;
|
||||
use Overtrue\Socialite\Providers\OpenWeWork;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
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 array_merge;
|
||||
|
||||
class Application implements ApplicationInterface
|
||||
{
|
||||
use InteractWithCache;
|
||||
use InteractWithClient;
|
||||
use InteractWithConfig;
|
||||
use InteractWithHttpClient;
|
||||
use InteractWithServerRequest;
|
||||
use InteractWithClient;
|
||||
use LoggerAwareTrait;
|
||||
|
||||
protected ?ServerInterface $server = null;
|
||||
|
||||
@ -43,6 +51,8 @@ class Application implements ApplicationInterface
|
||||
|
||||
protected ?AccessTokenInterface $suiteAccessToken = null;
|
||||
|
||||
protected ?AuthorizerAccessToken $authorizerAccessToken = null;
|
||||
|
||||
public function getAccount(): AccountInterface
|
||||
{
|
||||
if (! $this->account) {
|
||||
@ -247,21 +257,14 @@ class Application implements ApplicationInterface
|
||||
?AccessTokenInterface $suiteAccessToken = null
|
||||
): AuthorizerAccessToken {
|
||||
$suiteAccessToken = $suiteAccessToken ?? $this->getSuiteAccessToken();
|
||||
$response = $this->getHttpClient()->request('POST', 'cgi-bin/service/get_corp_token', [
|
||||
'query' => [
|
||||
'suite_access_token' => $suiteAccessToken->getToken(),
|
||||
],
|
||||
'json' => [
|
||||
'auth_corpid' => $corpId,
|
||||
'permanent_code' => $permanentCode,
|
||||
],
|
||||
])->toArray(false);
|
||||
|
||||
if (empty($response['access_token'])) {
|
||||
throw new HttpException('Failed to get access_token: '.json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
return new AuthorizerAccessToken($corpId, accessToken: $response['access_token']);
|
||||
return new AuthorizerAccessToken(
|
||||
corpId: $corpId,
|
||||
permanentCodeOrAccessToken: $permanentCode,
|
||||
suiteAccessToken: $suiteAccessToken,
|
||||
cache: $this->getCache(),
|
||||
httpClient: $this->getHttpClient(),
|
||||
);
|
||||
}
|
||||
|
||||
public function createClient(): AccessTokenAwareClient
|
||||
@ -274,16 +277,52 @@ class Application implements ApplicationInterface
|
||||
))->setPresets($this->config->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function getAuthorizerClient(string $corpId, string $permanentCode, ?AccessTokenInterface $suiteAccessToken = null): AccessTokenAwareClient
|
||||
{
|
||||
return (new AccessTokenAwareClient(
|
||||
client: $this->getHttpClient(),
|
||||
accessToken: $this->getAuthorizerAccessToken($corpId, $permanentCode, $suiteAccessToken),
|
||||
failureJudge: fn (Response $response) => (bool) ($response->toArray()['errcode'] ?? 0),
|
||||
throw: (bool) $this->config->get('http.throw', true),
|
||||
))->setPresets($this->config->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function getJsApiTicket(string $corpId, string $permanentCode, ?AccessTokenInterface $suiteAccessToken = null): JsApiTicket
|
||||
{
|
||||
return new JsApiTicket(
|
||||
corpId: $corpId,
|
||||
cache: $this->getCache(),
|
||||
httpClient: $this->getAuthorizerClient($corpId, $permanentCode, $suiteAccessToken),
|
||||
);
|
||||
}
|
||||
|
||||
public function getOAuth(
|
||||
string $suiteId,
|
||||
?AccessTokenInterface $suiteAccessToken = null
|
||||
): SocialiteProviderInterface {
|
||||
$suiteAccessToken = $suiteAccessToken ?? $this->getSuiteAccessToken();
|
||||
|
||||
return (new OpenWeWork([
|
||||
return (new OpenWeWork(array_filter([
|
||||
'client_id' => $suiteId,
|
||||
'redirect_url' => $this->config->get('oauth.redirect_url'),
|
||||
]))->withSuiteTicket($this->getSuiteTicket()->getTicket())
|
||||
'base_url' => $this->config->get('http.base_uri'),
|
||||
])))->withSuiteTicket($this->getSuiteTicket()->getTicket())
|
||||
->withSuiteAccessToken($suiteAccessToken->getToken())
|
||||
->scopes((array) $this->config->get('oauth.scopes', ['snsapi_base']));
|
||||
}
|
||||
@ -294,10 +333,11 @@ class Application implements ApplicationInterface
|
||||
): SocialiteProviderInterface {
|
||||
$suiteAccessToken = $suiteAccessToken ?? $this->getSuiteAccessToken();
|
||||
|
||||
return (new OpenWeWork([
|
||||
return (new OpenWeWork(array_filter([
|
||||
'client_id' => $corpId,
|
||||
'redirect_url' => $this->config->get('oauth.redirect_url'),
|
||||
]))->withSuiteTicket($this->getSuiteTicket()->getTicket())
|
||||
'base_url' => $this->config->get('http.base_uri'),
|
||||
])))->withSuiteTicket($this->getSuiteTicket()->getTicket())
|
||||
->withSuiteAccessToken($suiteAccessToken->getToken())
|
||||
->scopes((array) $this->config->get('oauth.scopes', ['snsapi_base']));
|
||||
}
|
||||
|
||||
2
vendor/w7corp/easywechat/src/OpenWork/Authorization.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/OpenWork/Authorization.php
vendored
Executable file → Normal file
@ -12,7 +12,7 @@ use EasyWeChat\Kernel\Traits\HasAttributes;
|
||||
/**
|
||||
* @implements ArrayAccess<string, mixed>
|
||||
*/
|
||||
class Authorization implements ArrayAccess, Jsonable, Arrayable
|
||||
class Authorization implements Arrayable, ArrayAccess, Jsonable
|
||||
{
|
||||
use HasAttributes;
|
||||
|
||||
|
||||
127
vendor/w7corp/easywechat/src/OpenWork/AuthorizerAccessToken.php
vendored
Executable file → Normal file
127
vendor/w7corp/easywechat/src/OpenWork/AuthorizerAccessToken.php
vendored
Executable file → Normal file
@ -4,15 +4,39 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenWork;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken;
|
||||
use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use Stringable;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
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 Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class AuthorizerAccessToken implements AccessToken, Stringable
|
||||
class AuthorizerAccessToken implements RefreshableAccessToken, Stringable
|
||||
{
|
||||
public function __construct(protected string $corpId, protected string $accessToken)
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
public function __construct(
|
||||
protected string $corpId,
|
||||
protected string $permanentCodeOrAccessToken,
|
||||
protected ?AccessTokenInterface $suiteAccessToken = null,
|
||||
protected ?string $key = null,
|
||||
?CacheInterface $cache = null,
|
||||
?HttpClientInterface $httpClient = null,
|
||||
) {
|
||||
$this->httpClient = $httpClient ?? HttpClient::create(['base_uri' => 'https://qyapi.weixin.qq.com/']);
|
||||
$this->cache = $cache ?? new Psr16Cache(new FilesystemAdapter(namespace: 'easywechat', defaultLifetime: 1500));
|
||||
}
|
||||
|
||||
public function getCorpId(): string
|
||||
@ -20,23 +44,102 @@ class AuthorizerAccessToken implements AccessToken, Stringable
|
||||
return $this->corpId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function getToken(): string
|
||||
{
|
||||
return $this->accessToken;
|
||||
}
|
||||
if (! isset($this->suiteAccessToken)) {
|
||||
return $this->permanentCodeOrAccessToken;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->accessToken;
|
||||
$token = $this->cache->get($this->getKey());
|
||||
|
||||
if ($token && is_string($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
return $this->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
#[Pure]
|
||||
#[ArrayShape(['access_token' => 'string'])]
|
||||
public function toQuery(): array
|
||||
{
|
||||
return ['access_token' => $this->getToken()];
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key ?? $this->key = sprintf('open_work.authorizer.access_token.%s.%s', $this->corpId, $this->permanentCodeOrAccessToken);
|
||||
}
|
||||
|
||||
public function setKey(string $key): static
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function refresh(): string
|
||||
{
|
||||
if (! isset($this->suiteAccessToken)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$response = $this->httpClient->request('POST', 'cgi-bin/service/get_corp_token', [
|
||||
'query' => [
|
||||
'suite_access_token' => $this->suiteAccessToken->getToken(),
|
||||
],
|
||||
'json' => [
|
||||
'auth_corpid' => $this->corpId,
|
||||
'permanent_code' => $this->permanentCodeOrAccessToken,
|
||||
],
|
||||
])->toArray(false);
|
||||
|
||||
if (empty($response['access_token'])) {
|
||||
throw new HttpException('Failed to get access_token: '.json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
$this->cache->set($this->getKey(), $response['access_token'], intval($response['expires_in']));
|
||||
|
||||
return $response['access_token'];
|
||||
}
|
||||
}
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenWork/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Config.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/Account.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/Application.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/SuiteTicket.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Contracts/SuiteTicket.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Encryptor.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/Encryptor.php
vendored
Executable file → Normal file
165
vendor/w7corp/easywechat/src/OpenWork/JsApiTicket.php
vendored
Normal file
165
vendor/w7corp/easywechat/src/OpenWork/JsApiTicket.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenWork;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
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 Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function intval;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
class JsApiTicket
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
|
||||
protected CacheInterface $cache;
|
||||
|
||||
public function __construct(
|
||||
protected string $corpId,
|
||||
protected ?string $key = null,
|
||||
?CacheInterface $cache = null,
|
||||
?HttpClientInterface $httpClient = null
|
||||
) {
|
||||
$this->httpClient = $httpClient ?? HttpClient::create(['base_uri' => 'https://qyapi.weixin.qq.com/']);
|
||||
$this->cache = $cache ?? new Psr16Cache(new FilesystemAdapter(namespace: 'easywechat', defaultLifetime: 1500));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function createConfigSignature(string $nonce, int $timestamp, string $url, array $jsApiList = [], bool $debug = false, bool $beta = true): array
|
||||
{
|
||||
return [
|
||||
'appId' => $this->corpId,
|
||||
'nonceStr' => $nonce,
|
||||
'timestamp' => $timestamp,
|
||||
'url' => $url,
|
||||
'signature' => $this->getTicketSignature($this->getTicket(), $nonce, $timestamp, $url),
|
||||
'jsApiList' => $jsApiList,
|
||||
'debug' => $debug,
|
||||
'beta' => $beta,
|
||||
];
|
||||
}
|
||||
|
||||
public function getTicketSignature(string $ticket, string $nonce, int $timestamp, string $url): string
|
||||
{
|
||||
return sha1(sprintf('jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s', $ticket, $nonce, $timestamp, $url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function getTicket(): string
|
||||
{
|
||||
$key = $this->getKey();
|
||||
$ticket = $this->cache->get($key);
|
||||
|
||||
if ($ticket && is_string($ticket)) {
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
$response = $this->httpClient->request('GET', '/cgi-bin/get_jsapi_ticket')->toArray(false);
|
||||
|
||||
if (empty($response['ticket'])) {
|
||||
throw new HttpException('Failed to get jssdk ticket: '.json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
$this->cache->set($key, $response['ticket'], intval($response['expires_in']));
|
||||
|
||||
return $response['ticket'];
|
||||
}
|
||||
|
||||
public function setKey(string $key): static
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key ?? $this->key = sprintf('open_work.jsapi_ticket.%s', $this->corpId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function createAgentConfigSignature(int $agentId, string $nonce, int $timestamp, string $url, array $jsApiList = []): array
|
||||
{
|
||||
return [
|
||||
'corpid' => $this->corpId,
|
||||
'agentid' => $agentId,
|
||||
'nonceStr' => $nonce,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $this->getTicketSignature($this->getAgentTicket($agentId), $nonce, $timestamp, $url),
|
||||
'jsApiList' => $jsApiList,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws DecodingExceptionInterface
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws HttpException
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function getAgentTicket(int $agentId): string
|
||||
{
|
||||
$key = $this->getAgentKey($agentId);
|
||||
$ticket = $this->cache->get($key);
|
||||
|
||||
if ($ticket && is_string($ticket)) {
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
$response = $this->httpClient->request('GET', '/cgi-bin/ticket/get', ['query' => ['type' => 'agent_config']])->toArray(false);
|
||||
|
||||
if (empty($response['ticket'])) {
|
||||
throw new HttpException('Failed to get jssdk agentTicket: '.json_encode($response, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
$this->cache->set($key, $response['ticket'], intval($response['expires_in']));
|
||||
|
||||
return $response['ticket'];
|
||||
}
|
||||
|
||||
public function getAgentKey(int $agentId): string
|
||||
{
|
||||
return sprintf('%s.%s', $this->getKey(), $agentId);
|
||||
}
|
||||
}
|
||||
2
vendor/w7corp/easywechat/src/OpenWork/Message.php
vendored
Executable file → Normal file
2
vendor/w7corp/easywechat/src/OpenWork/Message.php
vendored
Executable file → Normal file
@ -9,6 +9,8 @@ namespace EasyWeChat\OpenWork;
|
||||
* @property string $ChangeType
|
||||
* @property string $SuiteTicket
|
||||
* @property string $SuiteId
|
||||
* @property string $MsgType
|
||||
* @property string $Event
|
||||
*/
|
||||
class Message extends \EasyWeChat\Kernel\Message
|
||||
{
|
||||
|
||||
8
vendor/w7corp/easywechat/src/OpenWork/ProviderAccessToken.php
vendored
Executable file → Normal file
8
vendor/w7corp/easywechat/src/OpenWork/ProviderAccessToken.php
vendored
Executable file → Normal file
@ -4,17 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenWork;
|
||||
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken as RefreshableAccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use function intval;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function intval;
|
||||
|
||||
class ProviderAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
@ -57,7 +59,7 @@ class ProviderAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
$token = $this->cache->get($this->getKey());
|
||||
|
||||
if ((bool) $token && \is_string($token)) {
|
||||
if ($token && \is_string($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
52
vendor/w7corp/easywechat/src/OpenWork/Server.php
vendored
Executable file → Normal file
52
vendor/w7corp/easywechat/src/OpenWork/Server.php
vendored
Executable file → Normal file
@ -10,35 +10,32 @@ 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 function func_get_args;
|
||||
use Nyholm\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
use function func_get_args;
|
||||
|
||||
class Server implements ServerInterface
|
||||
{
|
||||
use InteractWithHandlers;
|
||||
use RespondXmlMessage;
|
||||
use DecryptXmlMessage;
|
||||
use InteractWithHandlers;
|
||||
use InteractWithServerRequest;
|
||||
use RespondXmlMessage;
|
||||
|
||||
protected ServerRequestInterface $request;
|
||||
protected ?Closure $defaultSuiteTicketHandler = null;
|
||||
|
||||
protected Closure|null $defaultSuiteTicketHandler = null;
|
||||
|
||||
/**
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function __construct(
|
||||
protected Encryptor $encryptor,
|
||||
protected Encryptor $providerEncryptor,
|
||||
?ServerRequestInterface $request = null,
|
||||
) {
|
||||
$this->request = $request ?? RequestUtil::createDefaultServerRequest();
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,9 +45,9 @@ class Server implements ServerInterface
|
||||
*/
|
||||
public function serve(): ResponseInterface
|
||||
{
|
||||
$query = $this->request->getQueryParams();
|
||||
$query = $this->getRequest()->getQueryParams();
|
||||
|
||||
if ((bool) ($str = $query['echostr'] ?? '')) {
|
||||
if ($str = $query['echostr'] ?? '') {
|
||||
$response = $this->providerEncryptor->decrypt(
|
||||
$str,
|
||||
$query['msg_signature'] ?? '',
|
||||
@ -61,7 +58,7 @@ class Server implements ServerInterface
|
||||
return new Response(200, [], $response);
|
||||
}
|
||||
|
||||
$message = $this->getRequestMessage($this->request);
|
||||
$message = $this->getRequestMessage($this->getRequest());
|
||||
|
||||
$this->prepend($this->decryptRequestMessage());
|
||||
|
||||
@ -219,9 +216,30 @@ class Server implements ServerInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function handleResetPermanentCode(callable $handler): static
|
||||
{
|
||||
$this->with(function (Message $message, Closure $next) use ($handler): mixed {
|
||||
return $message->InfoType === 'reset_permanent_code' ? $handler($message, $next) : $next($message);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function handleChangeAppAdmin(callable $handler): static
|
||||
{
|
||||
$this->with(function (Message $message, Closure $next) use ($handler): mixed {
|
||||
return $message->MsgType === 'event' && $message->Event === 'change_app_admin' ? $handler(
|
||||
$message,
|
||||
$next
|
||||
) : $next($message);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function decryptRequestMessage(): Closure
|
||||
{
|
||||
$query = $this->request->getQueryParams();
|
||||
$query = $this->getRequest()->getQueryParams();
|
||||
|
||||
return function (Message $message, Closure $next) use ($query): mixed {
|
||||
$this->decryptMessage(
|
||||
@ -241,7 +259,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());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,7 +268,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();
|
||||
|
||||
|
||||
12
vendor/w7corp/easywechat/src/OpenWork/SuiteAccessToken.php
vendored
Executable file → Normal file
12
vendor/w7corp/easywechat/src/OpenWork/SuiteAccessToken.php
vendored
Executable file → Normal file
@ -4,20 +4,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace EasyWeChat\OpenWork;
|
||||
|
||||
use function abs;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\RefreshableAccessToken as RefreshableAccessTokenInterface;
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use EasyWeChat\OpenWork\Contracts\SuiteTicket as SuiteTicketInterface;
|
||||
use function intval;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use function json_encode;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
use function abs;
|
||||
use function intval;
|
||||
use function json_encode;
|
||||
|
||||
class SuiteAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
protected HttpClientInterface $httpClient;
|
||||
@ -61,7 +63,7 @@ class SuiteAccessToken implements RefreshableAccessTokenInterface
|
||||
{
|
||||
$token = $this->cache->get($this->getKey());
|
||||
|
||||
if ((bool) $token && \is_string($token)) {
|
||||
if ($token && \is_string($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
0
vendor/w7corp/easywechat/src/OpenWork/SuiteEncryptor.php
vendored
Executable file → Normal file
0
vendor/w7corp/easywechat/src/OpenWork/SuiteEncryptor.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/OpenWork/SuiteTicket.php
vendored
Executable file → Normal file
5
vendor/w7corp/easywechat/src/OpenWork/SuiteTicket.php
vendored
Executable file → Normal file
@ -6,13 +6,14 @@ namespace EasyWeChat\OpenWork;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\RuntimeException;
|
||||
use EasyWeChat\OpenWork\Contracts\SuiteTicket as SuiteTicketInterface;
|
||||
use function is_string;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use function sprintf;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
class SuiteTicket implements SuiteTicketInterface
|
||||
{
|
||||
protected CacheInterface $cache;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user