diff --git a/src/Library.php b/src/Library.php index 60a30365..7e7d3ac6 100644 --- a/src/Library.php +++ b/src/Library.php @@ -108,7 +108,7 @@ public function register() { // 动态加载全局配置 [$dir, $ext] = [$this->app->getBasePath(), $this->app->getConfigExt()]; - ToolsExtend::findFilesArray($dir, 2, function (SplFileInfo $info) use ($ext) { + ToolsExtend::find($dir, 2, function (SplFileInfo $info) use ($ext) { $info->isFile() && $info->getBasename() === "sys{$ext}" && include_once $info->getPathname(); }); if (is_file($file = "{$dir}common{$ext}")) include_once $file; diff --git a/src/extend/PhinxExtend.php b/src/extend/PhinxExtend.php index 32b629ee..b157c50c 100644 --- a/src/extend/PhinxExtend.php +++ b/src/extend/PhinxExtend.php @@ -338,13 +338,13 @@ private function _create_{$table}() private static function nextFile(string $class): string { [$snake, $items] = [Str::snake($class), [20010000000000]]; - ToolsExtend::findFilesArray(syspath('database/migrations'), 1, function (SplFileInfo $info) use ($snake, &$items) { + ToolsExtend::find(syspath('database/migrations'), 1, function (SplFileInfo $info) use ($snake, &$items) { if ($info->isFile()) { $bname = pathinfo($info->getBasename(), PATHINFO_FILENAME); $items[] = $version = intval(substr($bname, 0, 14)); if ($snake === substr($bname, 15) && unlink($info->getRealPath())) { if (is_dir($dataPath = $info->getPath() . DIRECTORY_SEPARATOR . $version)) { - ToolsExtend::removeEmptyDirectory($dataPath); + ToolsExtend::remove($dataPath); } } } diff --git a/src/extend/ToolsExtend.php b/src/extend/ToolsExtend.php index 01d441c6..5110fb0c 100644 --- a/src/extend/ToolsExtend.php +++ b/src/extend/ToolsExtend.php @@ -22,6 +22,7 @@ use FilesystemIterator; use Generator; use SplFileInfo; +use think\admin\Exception; /** * 通用工具扩展 @@ -30,6 +31,44 @@ */ class ToolsExtend { + + /** + * 扫描目录下的文件列表 + * @param string $path 扫描目录 + * @param ?integer $depth 扫描深度 + * @param string $ext 筛选后缀 + * @param boolean $short 相对路径 + * @return array + */ + public static function scan(string $path, ?int $depth = null, string $ext = '', bool $short = true): array + { + return static::find($path, $depth, function (SplFileInfo $info) use ($ext) { + return $info->isDir() || $ext === '' || strtolower($info->getExtension()) === strtolower($ext); + }, $short); + } + + /** + * 扫描目录并返回文件路径数组 + * @param string $path 扫描目录 + * @param ?integer $depth 扫描深度 + * @param ?Closure $filter 文件过滤,返回 false 表示放弃 + * @param boolean $short 是否返回相对于给定路径的短路径 + * @return array 包含文件路径的数组 + */ + public static function find(string $path, ?int $depth = null, ?Closure $filter = null, bool $short = true): array + { + [$info, $files] = [new SplFileInfo($path), []]; + if ($info->isDir() || $info->isFile()) { + if ($info->isFile() && ($filter === null || $filter($info) !== false)) { + $files[] = $short ? $info->getBasename() : $info->getPathname(); + } + if ($info->isDir()) foreach (static::findFilesYield($info->getPathname(), $depth, $filter) as $file) { + $files[] = $short ? substr($file->getPathname(), strlen($info->getPathname()) + 1) : $file->getPathname(); + } + } + return $files; + } + /** * 深度拷贝到指定目录 * @param string $frdir 来源目录 @@ -39,13 +78,13 @@ class ToolsExtend * @param boolean $remove 删除文件 * @return boolean */ - public static function copyfile(string $frdir, string $todir, array $files = [], bool $force = true, bool $remove = true): bool + public static function copy(string $frdir, string $todir, array $files = [], bool $force = true, bool $remove = true): bool { $frdir = rtrim($frdir, '\\/') . DIRECTORY_SEPARATOR; $todir = rtrim($todir, '\\/') . DIRECTORY_SEPARATOR; // 扫描目录文件 if (empty($files) && is_dir($frdir)) { - $files = static::findFilesArray($frdir, null, function (SplFileInfo $info) { + $files = static::find($frdir, null, function (SplFileInfo $info) { return $info->getBasename()[0] !== '.'; }); } @@ -60,7 +99,7 @@ public static function copyfile(string $frdir, string $todir, array $files = [], $remove && unlink($fromPath); } // 删除来源目录 - $remove && static::removeEmptyDirectory($frdir); + $remove && static::remove($frdir); return true; } @@ -69,8 +108,10 @@ public static function copyfile(string $frdir, string $todir, array $files = [], * @param string $path * @return boolean */ - public static function removeEmptyDirectory(string $path): bool + public static function remove(string $path): bool { + if (!file_exists($path)) return true; + if (is_file($path)) return unlink($path); $dirs = [$path]; iterator_to_array(self::findFilesYield($path, null, function (SplFileInfo $file) use (&$dirs) { $file->isDir() ? $dirs[] = $file->getPathname() : unlink($file->getPathname()); @@ -78,45 +119,30 @@ public static function removeEmptyDirectory(string $path): bool usort($dirs, function ($a, $b) { return strlen($b) <=> strlen($a); }); - foreach ($dirs as $dir) rmdir($dir); + foreach ($dirs as $dir) file_exists($dir) && is_dir($dir) && rmdir($dir); return !file_exists($path); } /** - * 扫描目录列表 - * @param string $path 扫描目录 - * @param ?integer $depth 扫描深度 - * @param string $filterExt 筛选后缀 - * @param boolean $shortPath 相对路径 - * @return array + * 兼容旧方式调用 + * @param string $method + * @param array $arguments + * @return array|bool + * @throws \think\admin\Exception */ - public static function scanDirectory(string $path, ?int $depth = null, string $filterExt = '', bool $shortPath = true): array + public static function __callStatic(string $method, array $arguments) { - return static::findFilesArray($path, $depth, function (SplFileInfo $info) use ($filterExt, &$files) { - return $info->isDir() || $filterExt === '' || strtolower($info->getExtension()) === strtolower($filterExt); - }, $shortPath); - } - - /** - * 扫描指定目录并返回文件路径数组 - * @param string $path 扫描目录 - * @param ?integer $depth 扫描深度 - * @param ?Closure $filter 文件过滤,返回 false 表示放弃 - * @param boolean $short 是否返回相对于给定路径的短路径 - * @return array 包含文件路径的数组 - */ - public static function findFilesArray(string $path, ?int $depth = null, ?Closure $filter = null, bool $short = true): array - { - [$info, $files] = [new SplFileInfo($path), []]; - if ($info->isDir() || $info->isFile()) { - if ($info->isFile() && ($filter === null || $filter($info) !== false)) { - $files[] = $short ? $info->getBasename() : $info->getPathname(); - } - if ($info->isDir()) foreach (static::findFilesYield($info->getPathname(), $depth, $filter) as $file) { - $files[] = $short ? substr($file->getPathname(), strlen($info->getPathname()) + 1) : $file->getPathname(); - } + $methods = [ + 'copyfile' => 'copy', + 'scandirectory' => 'scan', + 'findfilesarray' => 'find', + 'removeemptydirectory' => 'remove', + ]; + if ($real = $methods[strtolower($method)] ?? null) { + return self::{$real}(...$arguments); + } else { + throw new Exception("method not exists: ToolsExtend::{$method}()"); } - return $files; } /** @@ -130,15 +156,14 @@ public static function findFilesArray(string $path, ?int $depth = null, ?Closure */ private static function findFilesYield(string $path, ?int $depth = null, ?Closure $filter = null, bool $appendPath = false, int $currDepth = 1): Generator { - if (file_exists($path) && is_dir($path) && (!is_numeric($depth) || $currDepth <= $depth)) { + if (file_exists($path) && is_dir($path) && (is_null($depth) || $currDepth <= $depth)) { foreach (new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS) as $item) { - if ($filter === null || $filter($item) !== false) { - if ($item->isDir() && !$item->isLink()) { - $appendPath && yield $item; - yield from static::findFilesYield($item->getPathname(), $depth, $filter, $appendPath, $currDepth + 1); - } else { - yield $item; - } + if ($filter !== null && $filter($item) === false) continue; + if ($item->isDir() && !$item->isLink()) { + $appendPath && yield $item; + yield from static::findFilesYield($item->getPathname(), $depth, $filter, $appendPath, $currDepth + 1); + } else { + yield $item; } } } diff --git a/src/service/NodeService.php b/src/service/NodeService.php index ae83860f..b03b1ec4 100644 --- a/src/service/NodeService.php +++ b/src/service/NodeService.php @@ -119,7 +119,7 @@ public static function getMethods(bool $force = false): array $ignoreMethods = get_class_methods('\think\admin\Controller'); $ignoreAppNames = Library::$sapp->config->get('app.rbac_ignore', []); // 扫描所有代码控制器节点,更新节点缓存 - foreach (ToolsExtend::scanDirectory(Library::$sapp->getBasePath(), null, 'php') as $name) { + foreach (ToolsExtend::scan(Library::$sapp->getBasePath(), null, 'php') as $name) { if (preg_match("|^(\w+)/controller/(.+)\.php$|i", strtr($name, '\\', '/'), $matches)) { [, $appName, $className] = $matches; if (in_array($appName, $ignoreAppNames)) continue; @@ -130,7 +130,7 @@ public static function getMethods(bool $force = false): array foreach (Plugin::get() as $appName => $plugin) { if (in_array($appName, $ignoreAppNames)) continue; [$appPath, $appSpace] = [$plugin['path'], $plugin['space']]; - foreach (ToolsExtend::scanDirectory($appPath, null, 'php') as $name) { + foreach (ToolsExtend::scan($appPath, null, 'php') as $name) { if (preg_match("|^.*?controller/(.+)\.php$|i", strtr($name, '\\', '/'), $matches)) { static::_parseClass($appName, $appSpace, $matches[1], $ignoreMethods, $data); } @@ -208,7 +208,7 @@ public function __call(string $name, array $arguments) public static function __callStatic(string $name, array $arguments) { if ($name === 'scanDirectory') { - return ToolsExtend::scanDirectory(...$arguments); + return ToolsExtend::scan(...$arguments); } elseif ($name === 'getModules') { return ModuleService::getModules(...$arguments); } else { diff --git a/src/support/command/Publish.php b/src/support/command/Publish.php index dd82e0a2..fe738c29 100644 --- a/src/support/command/Publish.php +++ b/src/support/command/Publish.php @@ -87,15 +87,15 @@ private function copy(string $copy, bool $force = false) { // 复制系统配置文件 $frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'config'; - ToolsExtend::copyfile($frdir, syspath('config'), [], $force, false); + ToolsExtend::copy($frdir, syspath('config'), [], $force, false); // 复制静态资料文件 $frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'public'; - ToolsExtend::copyfile($frdir, syspath('public'), [], true, false); + ToolsExtend::copy($frdir, syspath('public'), [], true, false); // 复制数据库脚本 $frdir = rtrim($copy, '\\/') . DIRECTORY_SEPARATOR . 'database'; - ToolsExtend::copyfile($frdir, syspath('database/migrations'), [], $force, false); + ToolsExtend::copy($frdir, syspath('database/migrations'), [], $force, false); } /** diff --git a/src/support/middleware/MultAccess.php b/src/support/middleware/MultAccess.php index f4dc2260..c23fcecf 100644 --- a/src/support/middleware/MultAccess.php +++ b/src/support/middleware/MultAccess.php @@ -169,7 +169,7 @@ private function loadMultiApp(string $appPath): bool // 加载应用函数文件 if (is_file($file = "{$appPath}common{$ext}")) include_once $file; // 加载应用配置文件 - ToolsExtend::findFilesArray($appPath . 'config', 1, function (SplFileInfo $info) use ($ext) { + ToolsExtend::find($appPath . 'config', 1, function (SplFileInfo $info) use ($ext) { if ($info->isFile() && strtolower(".{$info->getExtension()}") === $ext) { $this->app->config->load($info->getPathname(), $info->getBasename($ext)); }