diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index dd9a4d17..6c066311 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -86,6 +86,14 @@ module.exports = { children: [ 'common/class-alias', ] + }, + { + title: '存储组件', + collapsable: true, + sidebarDepth: 2, + children: [ + 'store/file-system', + ] } ], '/update/': [ diff --git a/docs/components/bot/bot-context.md b/docs/components/bot/bot-context.md index d620c8ff..9e9536ad 100644 --- a/docs/components/bot/bot-context.md +++ b/docs/components/bot/bot-context.md @@ -149,8 +149,8 @@ if ($response instanceof \ActionResponse) { > 此方法仅在 `BotCommand` 或 `BotEvent` 内 `type` 为 `message` 的上下文中有效,且仅可在协程环境可用时使用。 -- 定义:`prompt($prompt = '', int $timeout = 600, string $timeout_prompt = '', bool $return_string = false)` -- 返回:`MessageSegment[]|string|false` +- 定义:`prompt($prompt = '', int $timeout = 600, string $timeout_prompt = '', bool $return_string = false, int $option = ZM_PROMPT_NONE)` +- 返回:`MessageSegment[]|string` 参数说明: @@ -158,6 +158,22 @@ if ($response instanceof \ActionResponse) { - `$timeout`:可选参数,用于指定等待回复的超时时间,单位为秒,如果不指定,将使用默认的 600 秒。 - `$timeout_prompt`:可选参数,用于指定等待回复超时时发送的提示消息,如果不指定,将不发送提示消息。 - `$return_string`:可选参数,用于指定是否返回字符串形式的消息,如果不指定,将返回消息段数组。 +- `$option`:可选参数,用于设置 prompt 等待回复提示语句和超时语句的额外选项 + +返回说明: + +`$return_string` 默认为 false,即等待消息回复后拿到的消息返回格式为消息段数组格式。 + +该函数只会在成功时候返回,如果超时,会抛出一个 `WaitTimeoutException` 异常,但会被 OneBot 处理器捕获并回复超时消息,使用此功能的开发者无需捕获此异常。 + +额外选项 `$option` 说明: + +- `ZM_PROMPT_NONE`:不附加任何特性,直接回复原内容(默认)。 +- `ZM_PROMPT_MENTION_USER`:在发送 `$prompt` 消息时,在消息前添加一个 at 该用户。(如果 `$prompt` 为空则该参数无效) +- `ZM_PROMPT_QUOTE_USER`:在发送 `$prompt` 消息时,引用当前上下文绑定的那条用户消息。(如果 `$prompt` 为空则该参数无效) +- `ZM_PROMPT_TIMEOUT_MENTION_USER`:在询问参数超时时,如果超时的消息不为空则在超时的消息前添加一个 at 该用户。 +- `ZM_PROMPT_TIMEOUT_QUOTE_SELF`:在询问参数超时时,如果 `$timeout_prompt` 和 `$prompt` 均不为空,则在发送超时提示语时引用自己发送的 `$prompt` 提示语。 +- `ZM_PROMPT_TIMEOUT_QUOTE_USER`:在询问参数超时时,如果超时的消息不为空则引用用户最开始触发该注解的消息。 示例: @@ -180,6 +196,7 @@ public function testString(\BotContext $ctx) // 如果用户回复了消息,那么 reply 将是一个字符串 // 如果用户没有回复消息,超时了,那下方的代码不会被执行,此处的事件流程将强制中断 $ctx->reply('你回复了:' . $reply); + $reply2 = $ctx->prompt('请再回复一条消息', 30, '你又超时了', true, ZM_PROMPT_TIMEOUT_QUOTE_SELF); } ``` @@ -192,6 +209,13 @@ public function testString(\BotContext $ctx) {type:1,content:'请回复一条消息'}, {type:2,content:'等待 600 秒以上'}, {type:1,content:'你超时了'}, +{type:0,content:'测试字符串'}, +{type:1,content:'请回复一条消息'}, +{type:0,content:'abab'}, +{type:1,content:'你回复了:abab'}, +{type:1,content:'请再回复一条消息'}, +{type:2,content:'等待 30 秒以上'}, +{type:4,quote:'请再回复一条消息',content:'你又超时了'}, ]" /> ## hasReplied() - 检查是否已回复 diff --git a/docs/components/store/file-system.md b/docs/components/store/file-system.md new file mode 100644 index 00000000..27bec09e --- /dev/null +++ b/docs/components/store/file-system.md @@ -0,0 +1,123 @@ +# FileSystem 文件系统 + +文件系统是框架内提供的一个简易的文件管理类。为了让使用框架的开发者更贴近原生的体验,减轻学习负担,这里的 FileSystem 仅提供一些增强的功能。 + +> 全命名空间:`ZM\Store\FileSystem`。 + +## scanDirFiles() - 扫描目录 + +递归或非递归扫描目录,可返回相对目录的文件列表或绝对目录的文件列表。(非常好用) + +- 定义:`scanDirFiles(string $dir, bool $recursive = true, $relative = false, bool $include_dir = false)` +- 返回:`bool|array` + +参数说明: + +- `$dir`:要扫描的目录,必须是绝对路径或 Phar 路径,且路径可读。 +- `$recursive`:是否递归扫描子目录,默认为 True,如果设置为 False,则只返回当前目录下的目录和文件列表。 +- `$relative`:是否返回相对路径结果。如果为 True,则返回的文件列表为所有文件相对于 `$dir` 目录的相对路径。 +- `$include_dir`:如果 `$recursive` 为 False,本项为 True,即非递归模式下,是否包含目录。 + +当目录无法扫描时,返回 False,并将错误信息由 Logger 发出。 + +我们假设扫描以下目录,该目录位置为 `/home/ab/test/`,内容有 + +``` +./ +└── test-app/ + ├── main.php + ├── empty/ + └── zmplugin.json +``` + +```php +$result = \ZM\Store\FileSystem::scanDirFiles('/home/ab/test/', true, false); +/* +结果: +[ + "/home/ab/test/test-app/main.php", + "/home/ab/test/test-app/zmplugin.json" +] + */ +$result2 = \ZM\Store\FileSystem::scanDirFiles('/home/ab/test/', false, true, true); +/* +结果: +[ + "test-app" +] +*/ +``` + +## isRelativePath() - 检查相对路径 + +检查路径是否为相对路径(根据第一个字符是否为"/"来判断)。 + +- 定义:`isRelativePath(string $path)` +- 返回:`bool` +- 参数 `$path`:路径 + +```php +dump(\ZM\Store\FileSystem::isRelativePath('/a/b/c')); // false +dump(\ZM\Store\FileSystem::isRelativePath('aba/bbb/ccc.php')); // true +dump(\ZM\Store\FileSystem::isRelativePath('C:\\Windows\\')); // false +``` + +## createDir() - 创建目录 + +这个方法封装了 `mkdir()` 方法,首先检查目录是否存在,如果不存在就递归创建。 + +路径默认创建的权限为 755,暂无法调整,如果需要调整,请创建后手动 chmod。 + +如果创建失败,则抛出一个 `\RuntimeException` 异常。 + +定义:`createDir(string $path)` + +```php +\ZM\Store\FileSystem::createDir('/path/to/your/directory'); +``` + +## getClassesPsr4() - PSR-4 方式读取类列表 + +根据 PSR-4 规则传入一个目录和基础命名空间,通过扫描文件的方式读取该目录下所有符合 PSR-4 规则的类名。 + +- 定义:`getClassesPsr4(string $dir, string $base_namespace, mixed $rule = null, bool|string $return_path_value = false)` +- 返回:`array` + +参数说明: + +- `$dir`:要扫描的 PSR-4 目录。 +- `$base_namespace`:该 PSR-4 目录级别的命名空间。 +- `$rule`:用于自定义识别过滤文件的回调,默认为 null,即自动使用内建规则。关于内建规则,见下方说明。 +- `$return_path_value`:是否返回文件路径,返回文件路径的话传入字符串。 + +内建规则说明: + +- 默认的内建规则中,如果扫描到的目标目录存在该文件的同名加 `.ignore` 后缀的文件,则忽略。 +- 如果扫描到的文件以 `script_` 或 `global_` 开头,则忽略。 +- 如果扫描到的文件在 `composer.json` 中的 `autoload`.`files` 列表中存在,则忽略。 + +如果 `$return_path_value` 为字符串,则结果返回一个 map 格式的数组,键名是类名,键值是该值和类的所在文件的拼接。 + +我们假设目录结构为:`src/TestApp` 的命名空间为 `\TestApp`,下面有文件 `Hello.php` 对应类 `TestApp\Hello`: + +```php +$result = \ZM\Store\FileSystem::getClassesPsr4('src/TestApp', 'TestApp\\'); +// 结果:["TestApp\\Hello"] +``` + +## 文件读写 + +框架默认推荐你使用 PHP 原生的读写文件方式,例如 `file_get_contents`,你也可以引入例如 flysystem 等外部组件。 +这取决于你个人的喜好,但在使用第三方文件系统库时需要注意是否兼容协程和多进程。 + +::: tip 提示 + +无论在使用 `FileSystem` 类上方列举提供的扩充功能,还是 PHP 原生的读写文件方式,在框架内涉及目录的位置尽量使用绝对路径。 + +框架提供了一系列目录常量,可以配合目录常量来构成绝对路径。有关常量的定义,见 [留个空TODO]()。 + +```php +$file = file_get_contents(WORKING_DIR . '/composer.json'); +``` + +:::