|
|
|
@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
|
|
|
|
|
<?php |
|
|
|
|
/** |
|
|
|
|
* Class DirScanner |
|
|
|
|
* TODO: 兼容windows系统目录结构 |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
Class DirScanner { |
|
|
|
@ -28,6 +29,8 @@ Class DirScanner {
@@ -28,6 +29,8 @@ Class DirScanner {
|
|
|
|
|
'keywords' => '关键词', |
|
|
|
|
'snapshot' => '快照图片', |
|
|
|
|
]; |
|
|
|
|
private $rootDir; //当前扫描的根目录 |
|
|
|
|
private $scanningDirLevel = 0; //当前扫描的目录深度 |
|
|
|
|
private $scanResults = []; //目录扫描结果 |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -69,11 +72,7 @@ Class DirScanner {
@@ -69,11 +72,7 @@ Class DirScanner {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//解析描述文件内容 |
|
|
|
|
private function parseDescriptionFiles($realpath, $extension) { |
|
|
|
|
if (!in_array($extension, $this->allowReadContentFileExtensions)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function parseDescriptionFiles($realpath) { |
|
|
|
|
$field = preg_replace('/^.+_([a-z0-9]+)\.txt$/i', "$1", $realpath); |
|
|
|
|
if ($field == $realpath) {return false;} |
|
|
|
|
$content = file_get_contents($realpath); |
|
|
|
@ -84,7 +83,19 @@ Class DirScanner {
@@ -84,7 +83,19 @@ Class DirScanner {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//解析快捷方式文件内容 |
|
|
|
|
private function parseShortCuts($realpath) { |
|
|
|
|
private function parseShortCuts($realpath, $filename) { |
|
|
|
|
$content = file_get_contents($realpath); |
|
|
|
|
if (empty($content) || !preg_match('/\[InternetShortcut\]/i', $content)) {return false;} |
|
|
|
|
|
|
|
|
|
preg_match('/URL=(\S+)/i', $content, $matches); |
|
|
|
|
if (empty($matches) || empty($matches[1])) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
'name' => $filename, |
|
|
|
|
'url' => $matches[1], |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据文件路径生成唯一编号 |
|
|
|
@ -112,6 +123,66 @@ Class DirScanner {
@@ -112,6 +123,66 @@ Class DirScanner {
|
|
|
|
|
return $valid; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据路径生成目录数组 |
|
|
|
|
private function getDirData($realpath, $files) { |
|
|
|
|
$id = $this->getId($realpath); |
|
|
|
|
return [ |
|
|
|
|
'id' => $id, |
|
|
|
|
'directory' => basename($realpath), |
|
|
|
|
'realpath' => $realpath, |
|
|
|
|
'path' => $this->getDirPath($realpath), |
|
|
|
|
'files' => $files, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据路径生成文件数组,兼容URL文件 |
|
|
|
|
private function getFileData($realpath, $dirLevel) { |
|
|
|
|
$id = $this->getId($realpath); |
|
|
|
|
$fp = fopen($realpath, 'r'); |
|
|
|
|
$fstat = fstat($fp); |
|
|
|
|
fclose($fp); |
|
|
|
|
$pathinfo = pathinfo($realpath); |
|
|
|
|
$extension = strtolower($pathinfo['extension']); |
|
|
|
|
return [ |
|
|
|
|
'id' => $id, |
|
|
|
|
'filename' => $pathinfo['filename'], |
|
|
|
|
'extension' => $extension, |
|
|
|
|
'fstat' => [ |
|
|
|
|
'size' => $fstat['size'], |
|
|
|
|
'atime' => $fstat['atime'], |
|
|
|
|
'mtime' => $fstat['mtime'], |
|
|
|
|
'ctime' => $fstat['ctime'], |
|
|
|
|
], |
|
|
|
|
'realpath' => $realpath, |
|
|
|
|
'path' => $this->getFilePath( $this->getDirectoryName($pathinfo['dirname'], $dirLevel), $pathinfo['filename'], $extension ), |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据路径和根目录获取当前扫描的目录深度 |
|
|
|
|
private function getScanningLevel($rootDir, $dirname) { |
|
|
|
|
$level = 0; |
|
|
|
|
|
|
|
|
|
if ($dirname == $rootDir) { |
|
|
|
|
$level = 1; |
|
|
|
|
}else { |
|
|
|
|
$dirname = preg_replace('/\/$/', '', $dirname); |
|
|
|
|
$dirs = explode('/', str_replace($rootDir, '', $dirname)); |
|
|
|
|
$level = count($dirs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $level; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据路径和当前扫描深度获取目录名 |
|
|
|
|
private function getDirectoryName($dirname, $dirLevel) { |
|
|
|
|
if ($dirLevel <= 0) {return basename($dirname);} |
|
|
|
|
$dirname = preg_replace('/\/$/', '', $dirname); |
|
|
|
|
$dirname = preg_replace('/^\//', '', $dirname); |
|
|
|
|
$names = explode('/', $dirname); |
|
|
|
|
if ($dirLevel >= count($names)) {return $dirname;} |
|
|
|
|
return implode('/', array_splice($names, -$dirLevel)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据文件生成防盗链网址 |
|
|
|
|
//参考:https://nginx.org/en/docs/http/ngx_http_secure_link_module.html#secure_link |
|
|
|
@ -139,6 +210,16 @@ Class DirScanner {
@@ -139,6 +210,16 @@ Class DirScanner {
|
|
|
|
|
|
|
|
|
|
//根据文件生成相对路径 |
|
|
|
|
protected function getFilePath($directory, $filename, $extension) { |
|
|
|
|
if (empty($directory)) { |
|
|
|
|
$directory = '/'; |
|
|
|
|
} |
|
|
|
|
if (!preg_match('/\/$/', $directory)) { |
|
|
|
|
$directory .= '/'; |
|
|
|
|
} |
|
|
|
|
if (!preg_match('/^\//', $directory)) { |
|
|
|
|
$directory = "/{$directory}"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$extensionPathMap = [ //默认每种文件读取内容最大大小 |
|
|
|
|
'txt' => '', |
|
|
|
|
'md' => '/view/', |
|
|
|
@ -168,6 +249,11 @@ Class DirScanner {
@@ -168,6 +249,11 @@ Class DirScanner {
|
|
|
|
|
return $path; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//根据目录生成相对路径 |
|
|
|
|
protected function getDirPath($realpath) { |
|
|
|
|
return '/list/?dir=' . urlencode(basename($realpath)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//设置Nginx防盗链开启或关闭,以及密钥、加密方式、超时时长 |
|
|
|
|
public function setNginxSecure($secureOn, $secret = '', $userIp = '', $pattern = '', $timeout = 0) { |
|
|
|
@ -269,6 +355,37 @@ Class DirScanner {
@@ -269,6 +355,37 @@ Class DirScanner {
|
|
|
|
|
|
|
|
|
|
//扫描目录获取目录和文件列表,支持指定目录扫描深度(目录级数) |
|
|
|
|
public function scan($dir, $levels = 3) { |
|
|
|
|
$tree = array(); |
|
|
|
|
|
|
|
|
|
$ignore_files = array('.', '..'); |
|
|
|
|
if (is_dir($dir)) { |
|
|
|
|
if (!preg_match('/\/$/', $dir)) {$dir .= '/';} |
|
|
|
|
if (empty($this->rootDir)) { |
|
|
|
|
$this->rootDir = $dir; |
|
|
|
|
} |
|
|
|
|
$this->scanningDirLevel = $this->getScanningLevel($this->rootDir, $dir); |
|
|
|
|
$nextLevels = $levels - $this->scanningDirLevel; |
|
|
|
|
|
|
|
|
|
$files = scandir($dir); |
|
|
|
|
foreach($files as $file) { |
|
|
|
|
if (in_array($file, $ignore_files)) {continue;} |
|
|
|
|
|
|
|
|
|
$realpath = realpath("{$dir}{$file}"); |
|
|
|
|
if (is_dir($realpath)) { |
|
|
|
|
$files = []; |
|
|
|
|
if ($nextLevels > 0) { |
|
|
|
|
$files = $this->scan($realpath, $nextLevels); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$tree[] = $this->getDirData($realpath, $files); |
|
|
|
|
}else { |
|
|
|
|
$tree[] = $this->getFileData($realpath, $this->scanningDirLevel); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return $tree; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|