mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-21 23:55:35 +08:00
Merge pull request #86 from zhamao-robot/phpstan-level-2
PHPStan 升级到 level 2
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
name: Build
|
||||
name: Increment Build Number
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -27,4 +27,4 @@ jobs:
|
||||
git config --global user.email 'noreply@github.com'
|
||||
git add src/ZM/ConsoleApplication.php
|
||||
git commit -m "increment build number"
|
||||
git push
|
||||
git push
|
||||
42
.github/workflows/integration-test.yml
vendored
42
.github/workflows/integration-test.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Integration Test
|
||||
name: Integration and Style Test
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -37,6 +37,8 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: swoole, posix, json
|
||||
env:
|
||||
SWOOLE_CONFIGURE_OPTS: --enable-openssl
|
||||
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
@@ -61,5 +63,41 @@ jobs:
|
||||
- name: Run Static Analysis
|
||||
run: "composer analyse"
|
||||
|
||||
- name: Run PHPUnit
|
||||
run: "composer test"
|
||||
|
||||
cs-check:
|
||||
name: PHP CS Fixer Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP 7.2
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "7.2"
|
||||
extensions: swoole, posix, json
|
||||
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
|
||||
- name: Validate composer.json
|
||||
run: "composer validate --strict"
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer Dependencies
|
||||
run: "composer install --prefer-dist --no-progress --optimize-autoloader"
|
||||
|
||||
- name: Run PHP CS Fixer Check
|
||||
run: "./vendor/bin/php-cs-fixer fix --dry-run --diff"
|
||||
run: "composer cs-fix -- --dry-run --diff"
|
||||
|
||||
@@ -5,3 +5,4 @@ parameters:
|
||||
- ./src/
|
||||
ignoreErrors:
|
||||
- '#Used constant OS_TYPE_(LINUX|WINDOWS) not found#'
|
||||
- '#Constant .* not found#'
|
||||
|
||||
@@ -11,10 +11,10 @@ class CQ
|
||||
{
|
||||
/**
|
||||
* at一下QQ用户(仅在QQ群支持at全体)
|
||||
* @param $qq
|
||||
* @return string
|
||||
* @param int|string $qq 用户QQ号/ID号
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function at($qq)
|
||||
public static function at($qq): string
|
||||
{
|
||||
if (is_numeric($qq) || $qq === 'all') {
|
||||
return '[CQ:at,qq=' . $qq . ']';
|
||||
@@ -25,10 +25,10 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送QQ原生表情
|
||||
* @param $id
|
||||
* @return string
|
||||
* @param int|string $id 表情ID
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function face($id)
|
||||
public static function face($id): string
|
||||
{
|
||||
if (is_numeric($id)) {
|
||||
return '[CQ:face,id=' . $id . ']';
|
||||
@@ -39,10 +39,14 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送图片
|
||||
* @param $file
|
||||
* @return string
|
||||
* @param string $file 文件的路径、URL或者base64编码的图片数据
|
||||
* @param bool $cache 是否缓存(默认为true)
|
||||
* @param bool $flash 是否闪照(默认为false)
|
||||
* @param bool $proxy 是否使用代理(默认为true)
|
||||
* @param int $timeout 超时时间(默认不超时)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function image($file, bool $cache = true, bool $flash = false, bool $proxy = true, int $timeout = -1)
|
||||
public static function image(string $file, bool $cache = true, bool $flash = false, bool $proxy = true, int $timeout = -1): string
|
||||
{
|
||||
return
|
||||
'[CQ:image,file=' . self::encode($file, true) .
|
||||
@@ -55,15 +59,19 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送语音
|
||||
* @param $file
|
||||
* @return string
|
||||
* @param string $file 文件的路径、URL或者base64编码的语音数据
|
||||
* @param bool $magic 是否加特技(默认为false)
|
||||
* @param bool $cache 是否缓存(默认为true)
|
||||
* @param bool $proxy 是否使用代理(默认为true)
|
||||
* @param int $timeout 超时时间(默认不超时)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function record($file, bool $magic = false, bool $cache = true, bool $proxy = true, int $timeout = -1)
|
||||
public static function record(string $file, bool $magic = false, bool $cache = true, bool $proxy = true, int $timeout = -1): string
|
||||
{
|
||||
return
|
||||
'[CQ:record,file=' . self::encode($file, true) .
|
||||
(!$cache ? ',cache=0' : '') .
|
||||
($magic ? ',magic=1' : '') .
|
||||
(!$cache ? ',cache=0' : '') .
|
||||
(!$proxy ? ',proxy=false' : '') .
|
||||
($timeout != -1 ? (',timeout=' . $timeout) : '') .
|
||||
']';
|
||||
@@ -71,10 +79,13 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送短视频
|
||||
* @param $file
|
||||
* @return string
|
||||
* @param string $file 文件的路径、URL或者base64编码的短视频数据
|
||||
* @param bool $cache 是否缓存(默认为true)
|
||||
* @param bool $proxy 是否使用代理(默认为true)
|
||||
* @param int $timeout 超时时间(默认不超时)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function video($file, bool $cache = true, bool $proxy = true, int $timeout = -1)
|
||||
public static function video(string $file, bool $cache = true, bool $proxy = true, int $timeout = -1): string
|
||||
{
|
||||
return
|
||||
'[CQ:video,file=' . self::encode($file, true) .
|
||||
@@ -86,60 +97,62 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送投掷骰子(只能在单条回复中单独使用)
|
||||
* @return string
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function rps()
|
||||
public static function rps(): string
|
||||
{
|
||||
return '[CQ:rps]';
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送掷骰子表情(只能在单条回复中单独使用)
|
||||
* @return string
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function dice()
|
||||
public static function dice(): string
|
||||
{
|
||||
return '[CQ:dice]';
|
||||
}
|
||||
|
||||
/**
|
||||
* 戳一戳(原窗口抖动,仅支持好友消息使用)
|
||||
* @return string
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function shake()
|
||||
public static function shake(): string
|
||||
{
|
||||
return '[CQ:shake]';
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送新的戳一戳
|
||||
* @param $type
|
||||
* @param $id
|
||||
* @return string
|
||||
* @param int|string $type 焯一戳类型
|
||||
* @param int|string $id 戳一戳ID号
|
||||
* @param string $name 戳一戳名称(可选)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function poke($type, $id, string $name = '')
|
||||
public static function poke($type, $id, string $name = ''): string
|
||||
{
|
||||
return "[CQ:poke,type={$type},id={$id}" . ($name != '' ? (',name=' . self::encode($name, true)) : '') . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送匿名消息
|
||||
* @return string
|
||||
* @param int $ignore 是否忽略错误(默认为1,0表示不忽略错误)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function anonymous(int $ignore = 1)
|
||||
public static function anonymous(int $ignore = 1): string
|
||||
{
|
||||
return '[CQ:anonymous' . ($ignore != 1 ? ',ignore=0' : '') . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送链接分享(只能在单条回复中单独使用)
|
||||
* @param $url
|
||||
* @param $title
|
||||
* @param null $content
|
||||
* @param null $image
|
||||
* @return string
|
||||
* @param string $url 分享地址
|
||||
* @param string $title 标题
|
||||
* @param null|string $content 卡片内容(可选)
|
||||
* @param null|string $image 卡片图片(可选)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function share($url, $title, $content = null, $image = null)
|
||||
public static function share(string $url, string $title, ?string $content = null, ?string $image = null): string
|
||||
{
|
||||
if ($content === null) {
|
||||
$c = '';
|
||||
@@ -156,26 +169,28 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送好友或群推荐名片
|
||||
* @param $type
|
||||
* @param $id
|
||||
* @return string
|
||||
* @param string $type 名片类型
|
||||
* @param int|string $id 好友或群ID
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function contact($type, $id)
|
||||
public static function contact(string $type, $id): string
|
||||
{
|
||||
return "[CQ:contact,type={$type},id={$id}]";
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送位置
|
||||
* @param $lat
|
||||
* @param $lon
|
||||
* @return string
|
||||
* @param float|string $lat 纬度
|
||||
* @param float|string $lon 经度
|
||||
* @param string $title 标题(可选)
|
||||
* @param string $content 卡片内容(可选)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function location($lat, $lon, string $title = '', string $content = '')
|
||||
public static function location($lat, $lon, string $title = '', string $content = ''): string
|
||||
{
|
||||
return '[CQ:location' .
|
||||
',lat=' . self::encode($lat, true) .
|
||||
',lon=' . self::encode($lon, true) .
|
||||
',lat=' . self::encode((string) $lat, true) .
|
||||
',lon=' . self::encode((string) $lon, true) .
|
||||
($title != '' ? (',title=' . self::encode($title, true)) : '') .
|
||||
($content != '' ? (',content=' . self::encode($content, true)) : '') .
|
||||
']';
|
||||
@@ -183,23 +198,18 @@ class CQ
|
||||
|
||||
/**
|
||||
* 发送音乐分享(只能在单条回复中单独使用)
|
||||
*
|
||||
* qq、163、xiami为内置分享,需要先通过搜索功能获取id后使用
|
||||
* custom为自定义分享
|
||||
* 当为自定义分享时:
|
||||
* $id_or_url 为音乐卡片点进去打开的链接(一般是音乐介绍界面啦什么的)
|
||||
* $audio 为音乐(如mp3文件)的HTTP链接地址(不可为空)
|
||||
* $title 为音乐卡片的标题,建议12字以内(不可为空)
|
||||
* $content 为音乐卡片的简介(可忽略)
|
||||
* $image 为音乐卡片的图片链接地址(可忽略)
|
||||
* @param $type
|
||||
* @param $id_or_url
|
||||
* @param null $audio
|
||||
* @param null $title
|
||||
* @param null $content
|
||||
* @param null $image
|
||||
* @return string
|
||||
*
|
||||
* @param string $type 分享类型(仅限 `qq`、`163`、`xiami` 或 `custom`)
|
||||
* @param int|string $id_or_url 当分享类型不是 `custom` 时,表示的是分享音乐的ID(需要先通过搜索功能获取id后使用),反之表示的是音乐卡片点入的链接
|
||||
* @param null|string $audio 当分享类型是 `custom` 时,表示为音乐(如mp3文件)的HTTP链接地址(不可为空)
|
||||
* @param null|string $title 当分享类型是 `custom` 时,表示为音乐卡片的标题,建议12字以内(不可为空)
|
||||
* @param null|string $content 当分享类型是 `custom` 时,表示为音乐卡片的简介(可忽略)
|
||||
* @param null|string $image 当分享类型是 `custom` 时,表示为音乐卡片的图片链接地址(可忽略)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function music($type, $id_or_url, $audio = null, $title = null, $content = null, $image = null)
|
||||
public static function music(string $type, $id_or_url, ?string $audio = null, ?string $title = null, ?string $content = null, ?string $image = null): string
|
||||
{
|
||||
switch ($type) {
|
||||
case 'qq':
|
||||
@@ -231,27 +241,60 @@ class CQ
|
||||
}
|
||||
}
|
||||
|
||||
public static function forward($id)
|
||||
/**
|
||||
* 合并转发消息
|
||||
* @param int|string $id 合并转发ID, 需要通过 `/get_forward_msg` API获取转发的具体内容
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function forward($id): string
|
||||
{
|
||||
return '[CQ:forward,id=' . self::encode($id) . ']';
|
||||
return '[CQ:forward,id=' . self::encode((string) $id) . ']';
|
||||
}
|
||||
|
||||
public static function node($user_id, $nickname, $content)
|
||||
/**
|
||||
* 合并转发消息节点
|
||||
* 特殊说明: 需要使用单独的API /send_group_forward_msg 发送, 并且由于消息段较为复杂, 仅支持Array形式入参。
|
||||
* 如果引用消息和自定义消息同时出现, 实际查看顺序将取消息段顺序。
|
||||
* 另外按 CQHTTP 文档说明, data 应全为字符串, 但由于需要接收message 类型的消息, 所以 仅限此Type的content字段 支持Array套娃
|
||||
* @deprecated 这个不推荐使用,因为 go-cqhttp 官方没有对其提供CQ码模式相关支持,仅支持Array模式发送
|
||||
* @param int|string $user_id 转发消息id
|
||||
* @param string $nickname 发送者显示名字
|
||||
* @param string $content 具体消息
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function node($user_id, string $nickname, string $content): string
|
||||
{
|
||||
return "[CQ:node,user_id={$user_id},nickname=" . self::encode($nickname, true) . ',content=' . self::encode($content, true) . ']';
|
||||
}
|
||||
|
||||
public static function xml($data)
|
||||
/**
|
||||
* XML消息
|
||||
* @param string $data xml内容, xml中的value部分
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function xml(string $data): string
|
||||
{
|
||||
return '[CQ:xml,data=' . self::encode($data, true) . ']';
|
||||
}
|
||||
|
||||
public static function json($data, $resid = 0)
|
||||
/**
|
||||
* JSON消息
|
||||
* @param string $data json内容
|
||||
* @param int $resid 0为走小程序通道,其他值为富文本通道(默认为0)
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function json(string $data, int $resid = 0): string
|
||||
{
|
||||
return '[CQ:json,data=' . self::encode($data, true) . ',resid=' . intval($resid) . ']';
|
||||
return '[CQ:json,data=' . self::encode($data, true) . ',resid=' . $resid . ']';
|
||||
}
|
||||
|
||||
public static function _custom(string $type_name, $params)
|
||||
/**
|
||||
* 返回一个自定义扩展的CQ码(支持自定义类型和参数)
|
||||
* @param string $type_name CQ码类型名称
|
||||
* @param array $params 参数
|
||||
* @return string CQ码
|
||||
*/
|
||||
public static function _custom(string $type_name, array $params): string
|
||||
{
|
||||
$code = '[CQ:' . $type_name;
|
||||
foreach ($params as $k => $v) {
|
||||
@@ -263,10 +306,11 @@ class CQ
|
||||
|
||||
/**
|
||||
* 反转义字符串中的CQ码敏感符号
|
||||
* @param mixed $msg
|
||||
* @param mixed $is_content
|
||||
* @param string $msg 字符串
|
||||
* @param bool $is_content 如果是解码CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true
|
||||
* @return string 转义后的CQ码
|
||||
*/
|
||||
public static function decode($msg, $is_content = false)
|
||||
public static function decode(string $msg, bool $is_content = false): string
|
||||
{
|
||||
$msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg);
|
||||
if ($is_content) {
|
||||
@@ -275,7 +319,12 @@ class CQ
|
||||
return $msg;
|
||||
}
|
||||
|
||||
public static function replace($str)
|
||||
/**
|
||||
* 简单反转义替换CQ码的方括号
|
||||
* @param string $str 字符串
|
||||
* @return string 字符串
|
||||
*/
|
||||
public static function replace(string $str): string
|
||||
{
|
||||
$str = str_replace('{{', '[', $str);
|
||||
return str_replace('}}', ']', $str);
|
||||
@@ -283,10 +332,11 @@ class CQ
|
||||
|
||||
/**
|
||||
* 转义CQ码的特殊字符,同encode
|
||||
* @param mixed $msg
|
||||
* @param mixed $is_content
|
||||
* @param string $msg 字符串
|
||||
* @param bool $is_content 如果是转义CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true
|
||||
* @return string 转义后的CQ码
|
||||
*/
|
||||
public static function escape($msg, $is_content = false)
|
||||
public static function escape(string $msg, bool $is_content = false): string
|
||||
{
|
||||
$msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg);
|
||||
if ($is_content) {
|
||||
@@ -297,10 +347,11 @@ class CQ
|
||||
|
||||
/**
|
||||
* 转义CQ码的特殊字符
|
||||
* @param mixed $msg
|
||||
* @param mixed $is_content
|
||||
* @param string $msg 字符串
|
||||
* @param bool $is_content 如果是转义CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true
|
||||
* @return string 转义后的CQ码
|
||||
*/
|
||||
public static function encode($msg, $is_content = false)
|
||||
public static function encode(string $msg, bool $is_content = false): string
|
||||
{
|
||||
$msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg);
|
||||
if ($is_content) {
|
||||
@@ -311,10 +362,10 @@ class CQ
|
||||
|
||||
/**
|
||||
* 移除消息中所有的CQ码并返回移除CQ码后的消息
|
||||
* @param $msg
|
||||
* @return string
|
||||
* @param string $msg 消息
|
||||
* @return string 消息内容
|
||||
*/
|
||||
public static function removeCQ($msg)
|
||||
public static function removeCQ(string $msg): string
|
||||
{
|
||||
$final = '';
|
||||
$last_end = 0;
|
||||
@@ -328,10 +379,11 @@ class CQ
|
||||
|
||||
/**
|
||||
* 获取消息中第一个CQ码
|
||||
* @param mixed $msg
|
||||
* @param mixed $is_object
|
||||
* @param string $msg 消息内容
|
||||
* @param bool $is_object 是否以对象形式返回,如果为False的话,返回数组形式(默认为false)
|
||||
* @return array|CQObject 返回的CQ码(数组或对象)
|
||||
*/
|
||||
public static function getCQ($msg, $is_object = false)
|
||||
public static function getCQ(string $msg, bool $is_object = false)
|
||||
{
|
||||
if (($head = mb_strpos($msg, '[CQ:')) !== false) {
|
||||
$key_offset = mb_substr($msg, $head);
|
||||
@@ -356,10 +408,11 @@ class CQ
|
||||
|
||||
/**
|
||||
* 获取消息中所有的CQ码
|
||||
* @param mixed $msg
|
||||
* @param mixed $is_object
|
||||
* @param string $msg 消息内容
|
||||
* @param bool $is_object 是否以对象形式返回,如果为False的话,返回数组形式(默认为false)
|
||||
* @return array|CQObject[] 返回的CQ码们(数组或对象)
|
||||
*/
|
||||
public static function getAllCQ($msg, $is_object = false)
|
||||
public static function getAllCQ(string $msg, bool $is_object = false): array
|
||||
{
|
||||
$cqs = [];
|
||||
$offset = 0;
|
||||
|
||||
@@ -13,7 +13,7 @@ use ZM\Utils\CoMessage;
|
||||
|
||||
trait CQAPI
|
||||
{
|
||||
/** @var null|Closure */
|
||||
/** @var null|Closure 过滤用的 */
|
||||
private static $filter;
|
||||
|
||||
public function __call($name, $arguments)
|
||||
@@ -33,12 +33,6 @@ trait CQAPI
|
||||
return $func_name . $postfix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $connection
|
||||
* @param $reply
|
||||
* @param |null $function
|
||||
* @return array|bool
|
||||
*/
|
||||
private function processAPI($connection, $reply, $function = null)
|
||||
{
|
||||
if (is_callable(self::$filter)) {
|
||||
@@ -57,7 +51,7 @@ trait CQAPI
|
||||
|
||||
private function processWebsocketAPI($connection, $reply, $function = false)
|
||||
{
|
||||
$api_id = ZMAtomic::get('wait_msg_id')->add(1);
|
||||
$api_id = ZMAtomic::get('wait_msg_id')->add();
|
||||
$reply['echo'] = $api_id;
|
||||
if (server()->push($connection->getFd(), json_encode($reply))) {
|
||||
if ($function === true) {
|
||||
@@ -89,14 +83,10 @@ trait CQAPI
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $connection
|
||||
* @param $reply
|
||||
* @param null $function
|
||||
* @noinspection PhpUnusedParameterInspection
|
||||
*/
|
||||
private function processHttpAPI($connection, $reply, $function = null): bool
|
||||
{
|
||||
unset($connection, $reply, $function);
|
||||
// TODO: HTTP方式处理API的代码还没写
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class GoCqhttpAPIV11
|
||||
* 获取频道系统内BOT的资料
|
||||
* 响应字段:nickname, tiny_id, avatar_url
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E7%B3%BB%E7%BB%9F%E5%86%85bot%E7%9A%84%E8%B5%84%E6%96%99
|
||||
* @return array|bool
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function getGuildServiceProfile()
|
||||
{
|
||||
@@ -39,7 +39,7 @@ class GoCqhttpAPIV11
|
||||
/**
|
||||
* 获取频道列表
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8
|
||||
* @return array|bool
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function getGuildList()
|
||||
{
|
||||
@@ -51,8 +51,8 @@ class GoCqhttpAPIV11
|
||||
/**
|
||||
* 通过访客获取频道元数据
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E9%80%9A%E8%BF%87%E8%AE%BF%E5%AE%A2%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%85%83%E6%95%B0%E6%8D%AE
|
||||
* @param $guild_id
|
||||
* @return array|bool
|
||||
* @param int|string $guild_id 频道ID
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function getGuildMetaByGuest($guild_id)
|
||||
{
|
||||
@@ -67,9 +67,9 @@ class GoCqhttpAPIV11
|
||||
/**
|
||||
* 获取子频道列表
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E5%AD%90%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8
|
||||
* @param $guild_id
|
||||
* @param false $no_cache
|
||||
* @return array|bool
|
||||
* @param int|string $guild_id 频道ID
|
||||
* @param false $no_cache 禁用缓存(默认为false)
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function getGuildChannelList($guild_id, bool $no_cache = false)
|
||||
{
|
||||
@@ -85,8 +85,8 @@ class GoCqhttpAPIV11
|
||||
/**
|
||||
* 获取频道成员列表
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E6%88%90%E5%91%98%E5%88%97%E8%A1%A8
|
||||
* @param $guild_id
|
||||
* @return array|bool
|
||||
* @param int|string $guild_id 频道ID
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function getGuildMembers($guild_id)
|
||||
{
|
||||
@@ -101,12 +101,12 @@ class GoCqhttpAPIV11
|
||||
/**
|
||||
* 发送信息到子频道
|
||||
* @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E5%8F%91%E9%80%81%E4%BF%A1%E6%81%AF%E5%88%B0%E5%AD%90%E9%A2%91%E9%81%93
|
||||
* @param $guild_id
|
||||
* @param $channel_id
|
||||
* @param $message
|
||||
* @return array|bool
|
||||
* @param int|string $guild_id 频道ID
|
||||
* @param int|string $channel_id 子频道ID
|
||||
* @param string $message 信息内容
|
||||
* @return array|bool 返回API调用结果(数组)或异步API调用状态(bool)
|
||||
*/
|
||||
public function sendGuildChannelMsg($guild_id, $channel_id, $message)
|
||||
public function sendGuildChannelMsg($guild_id, $channel_id, string $message)
|
||||
{
|
||||
return $this->processAPI($this->connection, [
|
||||
'action' => $this->getActionName($this->prefix, __FUNCTION__),
|
||||
|
||||
279
tests/ZM/API/CQTest.php
Normal file
279
tests/ZM/API/CQTest.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\ZM\API;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZM\API\CQ;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class CQTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerShare
|
||||
* @param mixed $url
|
||||
* @param mixed $title
|
||||
* @param mixed $content
|
||||
* @param mixed $image
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testShare($url, $title, $content, $image, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, CQ::share($url, $title, $content, $image));
|
||||
}
|
||||
|
||||
public function providerShare(): array
|
||||
{
|
||||
return [
|
||||
'all' => [
|
||||
'https://www.baidu.com',
|
||||
'hello',
|
||||
'world',
|
||||
'https://www.baidu.com/img/bd_logo1.png',
|
||||
'[CQ:share,url=https://www.baidu.com,title=hello,content=world,image=https://www.baidu.com/img/bd_logo1.png]',
|
||||
],
|
||||
'url title' => [
|
||||
'https://www.baidu.com',
|
||||
'123',
|
||||
null,
|
||||
null,
|
||||
'[CQ:share,url=https://www.baidu.com,title=123]',
|
||||
],
|
||||
'url title content' => [
|
||||
'https://www.baidu.com',
|
||||
'123',
|
||||
'456',
|
||||
null,
|
||||
'[CQ:share,url=https://www.baidu.com,title=123,content=456]',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testShake()
|
||||
{
|
||||
$this->assertEquals('[CQ:shake]', CQ::shake());
|
||||
}
|
||||
|
||||
public function testLocation()
|
||||
{
|
||||
$this->assertEquals('[CQ:location,lat=23.137466,lon=113.352425]', CQ::location(23.137466, 113.352425));
|
||||
}
|
||||
|
||||
public function testVideo()
|
||||
{
|
||||
$this->assertEquals('[CQ:video,file=https://www.baidu.com,cache=0,proxy=false,timeout=20]', CQ::video('https://www.baidu.com', false, false, 20));
|
||||
}
|
||||
|
||||
public function testContact()
|
||||
{
|
||||
$this->assertEquals('[CQ:contact,type=qq,id=123456789]', CQ::contact('qq', '123456789'));
|
||||
}
|
||||
|
||||
public function testForward()
|
||||
{
|
||||
$this->assertEquals('[CQ:forward,id=123456789]', CQ::forward(123456789));
|
||||
}
|
||||
|
||||
public function testAnonymous()
|
||||
{
|
||||
$this->assertEquals('[CQ:anonymous,ignore=0]', CQ::anonymous(0));
|
||||
}
|
||||
|
||||
public function testCustom()
|
||||
{
|
||||
$this->assertEquals('[CQ:test,type=test,data=hello]', CQ::_custom('test', ['type' => 'test', 'data' => 'hello']));
|
||||
}
|
||||
|
||||
public function testEscape()
|
||||
{
|
||||
$this->assertEquals('hello[],', CQ::escape('hello[],'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMusic
|
||||
* @param mixed $data
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testMusic($data, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, CQ::music(...$data));
|
||||
}
|
||||
|
||||
public function providerMusic(): array
|
||||
{
|
||||
return [
|
||||
'music qq' => [
|
||||
['qq', '123456789'],
|
||||
'[CQ:music,type=qq,id=123456789]',
|
||||
],
|
||||
'music 163' => [
|
||||
['163', '123456789'],
|
||||
'[CQ:music,type=163,id=123456789]',
|
||||
],
|
||||
'music xiami' => [
|
||||
['xiami', '123456789'],
|
||||
'[CQ:music,type=xiami,id=123456789]',
|
||||
],
|
||||
'music custom' => [
|
||||
['custom', '123456789'],
|
||||
' ',
|
||||
],
|
||||
'music custom url audio title' => [
|
||||
['custom', '123456789', 'test', 'test1'],
|
||||
'[CQ:music,type=custom,url=123456789,audio=test,title=test1]',
|
||||
],
|
||||
'music custom url audio title content' => [
|
||||
['custom', '123456789', 'test', 'test1', 'test2'],
|
||||
'[CQ:music,type=custom,url=123456789,audio=test,title=test1,content=test2]',
|
||||
],
|
||||
'music custom url audio title content image' => [
|
||||
['custom', '123456789', 'test', 'test1', 'test2', 'test3'],
|
||||
'[CQ:music,type=custom,url=123456789,audio=test,title=test1,content=test2,image=test3]',
|
||||
],
|
||||
'music custom test' => [
|
||||
['custom test', '123456789', 'test', 'test1', 'test2', 'test3'],
|
||||
' ',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testPoke()
|
||||
{
|
||||
$this->assertEquals('[CQ:poke,type=id,id=123456789]', CQ::poke('id', '123456789'));
|
||||
}
|
||||
|
||||
public function testJson()
|
||||
{
|
||||
$this->assertEquals('[CQ:json,data={"a":"b["},resid=1]', CQ::json(json_encode(['a' => 'b[']), 1));
|
||||
}
|
||||
|
||||
public function testEncode()
|
||||
{
|
||||
$this->assertEquals('hello[],', CQ::encode('hello[],'));
|
||||
}
|
||||
|
||||
public function testDice()
|
||||
{
|
||||
$this->assertEquals('[CQ:dice]', CQ::dice());
|
||||
}
|
||||
|
||||
public function testRecord()
|
||||
{
|
||||
$this->assertEquals('[CQ:record,file=https://www.baidu.com,cache=0]', CQ::record('https://www.baidu.com', false, false));
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
$this->assertEquals('hello[],', CQ::decode('hello[],'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRemoveCQ
|
||||
* @param mixed $msg
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testRemoveCQ($msg, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, CQ::removeCQ($msg));
|
||||
}
|
||||
|
||||
public function providerRemoveCQ(): array
|
||||
{
|
||||
return [
|
||||
'remove cq 1' => ['hello[CQ:at,qq=123456789],', 'hello,'],
|
||||
'remove cq 2' => ['hello[CQ:at,qq=123456789,', 'hello[CQ:at,qq=123456789,'],
|
||||
'remove cq 3' => ['[CQ:dice]hello[CQ:at,qq=123456789]', 'hello'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetAllCQ()
|
||||
{
|
||||
$array = CQ::getAllCQ('[CQ:dice][CQ:at,qq=123456789]');
|
||||
$this->assertEquals([
|
||||
[
|
||||
'type' => 'dice',
|
||||
'start' => 0,
|
||||
'end' => 8,
|
||||
],
|
||||
[
|
||||
'type' => 'at',
|
||||
'params' => [
|
||||
'qq' => '123456789',
|
||||
],
|
||||
'start' => 9,
|
||||
'end' => 28,
|
||||
],
|
||||
], $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerGetCQ
|
||||
* @param mixed $cq
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testGetCQ($cq, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, CQ::getCQ($cq));
|
||||
}
|
||||
|
||||
public function providerGetCQ(): array
|
||||
{
|
||||
return [
|
||||
'one dice' => ['[CQ:dice]', [
|
||||
'type' => 'dice',
|
||||
'start' => 0,
|
||||
'end' => 8,
|
||||
]],
|
||||
'one at' => ['[CQ:at,qq=123456789]', [
|
||||
'type' => 'at',
|
||||
'params' => [
|
||||
'qq' => '123456789',
|
||||
],
|
||||
'start' => 0,
|
||||
'end' => 19,
|
||||
]],
|
||||
'invalid cq 1' => ['[CQ:at,qq=123456789', null],
|
||||
'invalid cq 2' => ['[CQ;at,qq=123456789]', null],
|
||||
];
|
||||
}
|
||||
|
||||
public function testImage()
|
||||
{
|
||||
$this->assertEquals('[CQ:image,file=https://www.baidu.com]', CQ::image('https://www.baidu.com'));
|
||||
}
|
||||
|
||||
public function testRps()
|
||||
{
|
||||
$this->assertEquals('[CQ:rps]', CQ::rps());
|
||||
}
|
||||
|
||||
public function testReplace()
|
||||
{
|
||||
$this->assertEquals('[]', CQ::replace('{{}}'));
|
||||
}
|
||||
|
||||
public function testAt()
|
||||
{
|
||||
$this->assertEquals('[CQ:at,qq=123456789]', CQ::at('123456789'));
|
||||
$this->assertEquals(' ', CQ::at(null));
|
||||
}
|
||||
|
||||
public function testXml()
|
||||
{
|
||||
$this->assertEquals('[CQ:xml,data=<xml></xml>]', CQ::xml('<xml></xml>'));
|
||||
}
|
||||
|
||||
public function testFace()
|
||||
{
|
||||
$this->assertEquals('[CQ:face,id=1]', CQ::face(1));
|
||||
$this->assertEquals(' ', CQ::face(null));
|
||||
}
|
||||
|
||||
public function testNode()
|
||||
{
|
||||
$this->assertEquals('[CQ:node,user_id=test,nickname=content,content=blah]', CQ::node('test', 'content', 'blah'));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Tests\ZM\Utils;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Throwable;
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\API\CQ;
|
||||
use ZM\Event\EventManager;
|
||||
@@ -157,16 +158,27 @@ class MessageUtilTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function testDownloadCQImage(): void
|
||||
{
|
||||
if (file_exists(DataProvider::getDataFolder('images') . '/test.jpg')) {
|
||||
unlink(DataProvider::getDataFolder('images') . '/test.jpg');
|
||||
}
|
||||
$msg = '[CQ:image,file=test.jpg,url=https://zhamao.xin/file/hello.jpg]';
|
||||
$result = MessageUtil::downloadCQImage($msg);
|
||||
$this->assertIsArray($result);
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertFileExists(DataProvider::getDataFolder('images') . '/test.jpg');
|
||||
unlink(DataProvider::getDataFolder('images') . '/test.jpg');
|
||||
|
||||
try {
|
||||
$result = MessageUtil::downloadCQImage($msg);
|
||||
$this->assertIsArray($result);
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertFileExists(DataProvider::getDataFolder('images') . '/test.jpg');
|
||||
unlink(DataProvider::getDataFolder('images') . '/test.jpg');
|
||||
} catch (Throwable $e) {
|
||||
if (strpos($e->getMessage(), 'enable-openssl') !== false) {
|
||||
$this->markTestSkipped('OpenSSL is not enabled');
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user