new feature: simple file manage
目前只实现了目录切换 路径显示 文件下载
This commit is contained in:
Chenx221 2024-02-10 17:41:07 +08:00
parent be6988e564
commit 9159880f12
6 changed files with 144 additions and 5 deletions

View File

@ -4,4 +4,6 @@ return [
'adminEmail' => 'admin@example.com', 'adminEmail' => 'admin@example.com',
'senderEmail' => 'noreply@example.com', 'senderEmail' => 'noreply@example.com',
'senderName' => 'Example.com mailer', 'senderName' => 'Example.com mailer',
// data directory is used to store uploaded files by the user (e.g. root dir for every user's home)
'dataDirectory' => '@app/data',
]; ];

View File

@ -22,6 +22,7 @@ $config = [
'user' => [ 'user' => [
'identityClass' => 'app\models\User', 'identityClass' => 'app\models\User',
'enableAutoLogin' => true, 'enableAutoLogin' => true,
'loginUrl' => ['user/login'], // 登录地址
], ],
'errorHandler' => [ 'errorHandler' => [
'errorAction' => 'site/error', 'errorAction' => 'site/error',

View File

@ -0,0 +1,88 @@
<?php
namespace app\controllers;
use Yii;
use yii\web\NotFoundHttpException;
use yii\web\Response;
class HomeController extends \yii\web\Controller
{
/**
* @return string|Response
* @throws NotFoundHttpException
*/
public function actionIndex($directory = null)
{
if (Yii::$app->user->isGuest) {
return $this->redirect(Yii::$app->user->loginUrl);
}
$rootDataDirectory = Yii::getAlias(Yii::$app->params['dataDirectory']);
$userId = Yii::$app->user->id;
if ($directory == null | $directory == '.') {
$parentDirectory = null;
} else {
$parentDirectory = dirname($directory);
}
$directoryContents = $this->getDirectoryContents(join(DIRECTORY_SEPARATOR, [$rootDataDirectory, $userId, $directory ?: '.']));
return $this->render('index', [
'directoryContents' => $directoryContents,
'parentDirectory' => $parentDirectory,
'directory' => $directory, // 将$directory传递给视图
]);
}
/**
* 获取指定路径下的文件和文件夹内容
* @param string $path 路径
* @return array 文件和文件夹内容数组
* @throws NotFoundHttpException 如果路径不存在
*/
protected function getDirectoryContents($path)
{
// 确定路径是否存在
if (!is_dir($path)) {
throw new NotFoundHttpException('Directory not found.');
}
// 获取路径下的所有文件和文件夹
$directoryContents = scandir($path);
return array_diff($directoryContents, ['.', '..']);
}
/**
* 下载指定路径下的文件
* @param string $relativePath 文件的相对路径
* @throws NotFoundHttpException 如果文件不存在
*/
public function actionDownload($relativePath)
{
// 对相对路径进行解码
$relativePath = rawurldecode($relativePath);
// 检查相对路径是否只包含允许的字符
if (!preg_match('/^[\w\-.\/]+$/u', $relativePath)) {
throw new NotFoundHttpException('Invalid file path.');
}
// 确定文件的绝对路径
$absolutePath = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id . '/' . $relativePath;
// 使用realpath函数解析路径并检查解析后的路径是否在预期的目录中
$realPath = realpath($absolutePath);
$dataDirectory = str_replace('/', '\\', Yii::getAlias(Yii::$app->params['dataDirectory']));
if (!$realPath || !str_starts_with($realPath, $dataDirectory)) {
throw new NotFoundHttpException('File not found.');
}
// 检查文件是否存在
if (!file_exists($realPath)) {
throw new NotFoundHttpException('File not found.');
}
// 将文件发送给用户进行下载
Yii::$app->response->sendFile($realPath)->send();
}
}

48
views/home/index.php Normal file
View File

@ -0,0 +1,48 @@
<?php
/* @var $this yii\web\View */
/* @var $directoryContents array 文件和文件夹内容数组 */
/* @var $parentDirectory string 父目录 */
/* @var $directory string 当前路径 */
use yii\bootstrap5\Html;
$this->title = '文件管理';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="home-directory">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('HOME', ['home/index']) ?>
<?php if ($directory !== null): ?>
<?php
$parts = explode('/', $directory);
$path = '';
foreach ($parts as $part):
$path .= $part;
echo ' / ' . Html::a($part, ['home/index', 'directory' => $path]);
$path .= '/';
endforeach;
?>
<?php endif; ?>
</p>
<ul>
<?php foreach ($directoryContents as $item): ?>
<?php $relativePath = $directory ? $directory . '/' . $item : $item; ?>
<!-- 修复错误的绝对路径问题-->
<?php $absolutePath = Yii::getAlias('@app') . '/data/' . Yii::$app->user->id . '/' . $relativePath; ?>
<?php if (is_dir($absolutePath)): ?>
<!-- 文件夹 -->
<li><?= Html::a($item, ['home/index', 'directory' => $relativePath]) ?></li>
<?php else: ?>
<!-- 文件 -->
<li><?= Html::a($item, ['home/download', 'relativePath' => $relativePath]) ?>
(<?= Html::a('下载', ['home/download', 'relativePath' => $relativePath]) ?>)
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>

View File

@ -41,12 +41,12 @@ $this->registerLinkTag(['rel' => 'icon', 'type' => 'image/x-icon', 'href' => Yii
'options' => ['class' => 'navbar-nav'], 'options' => ['class' => 'navbar-nav'],
'items' => [ 'items' => [
['label' => '首页', 'url' => ['/site/index']], ['label' => '首页', 'url' => ['/site/index']],
['label' => '文件', 'url' => ['/site/about']], ['label' => '我的文件', 'url' => ['/home/index']],
['label' => '分享', 'url' => ['/site/about']], ['label' => '分享管理', 'url' => ['/site/about']],
['label' => '个人设置', 'url' => ['/site/about']], ['label' => '个人设置', 'url' => ['/site/about']],
['label' => '系统设置', 'url' => ['/site/contact']], ['label' => '系统设置', 'url' => ['/site/contact']],
['label' => '客户端下载', 'url' => ['/site/contact']], ['label' => '应用下载', 'url' => ['/site/contact']],
['label' => 'API', 'url' => ['/site/about']], ['label' => 'API文档', 'url' => ['/site/about']],
Yii::$app->user->isGuest Yii::$app->user->isGuest
? ['label' => '登录', 'url' => ['/user/login']] ? ['label' => '登录', 'url' => ['/user/login']]
: '<li class="nav-item">' : '<li class="nav-item">'

View File

@ -8,7 +8,7 @@
use yii\bootstrap5\ActiveForm; use yii\bootstrap5\ActiveForm;
use yii\bootstrap5\Html; use yii\bootstrap5\Html;
$this->title = 'Login'; $this->title = '这里是弃用的登录,请不要在这里登录,开发后期将会移除这个页面';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
?> ?>
<div class="site-login"> <div class="site-login">