一定的改进

新增重命名功能
下载功能暂未完成
一点点界面的美化
*目前已知一些安全问题待解决
This commit is contained in:
Chenx221 2024-02-11 16:04:21 +08:00
parent a80594bcb0
commit 480796d55d
Signed by: chenx221
GPG Key ID: D7A9EC07024C3021
3 changed files with 206 additions and 9 deletions

View File

@ -2,13 +2,36 @@
namespace app\controllers; namespace app\controllers;
use app\models\RenameForm;
use app\utils\FileTypeDetector; use app\utils\FileTypeDetector;
use InvalidArgumentException;
use Yii; use Yii;
use yii\filters\VerbFilter;
use yii\helpers\ArrayHelper;
use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\web\Response; use yii\web\Response;
class HomeController extends \yii\web\Controller class HomeController extends Controller
{ {
public function behaviors()
{
return array_merge(
parent::behaviors(),
[
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
'index' => ['GET'],
'download' => ['GET'],
'rename' => ['POST'],
'delete' => ['POST'],
],
],
]
);
}
/** /**
* diplay the page of the file manager (accepts a directory parameter like cd command) * diplay the page of the file manager (accepts a directory parameter like cd command)
* visit it via https://devs.chenx221.cyou:8081/index.php?r=home * visit it via https://devs.chenx221.cyou:8081/index.php?r=home
@ -65,7 +88,6 @@ class HomeController extends \yii\web\Controller
/** /**
* 下载指定路径下的文件 * 下载指定路径下的文件
* must be provided with a relative path of the file
* download link:https://devs.chenx221.cyou:8081/index.php?r=home%2Fdownload&relativePath={the relative path of the file} * download link:https://devs.chenx221.cyou:8081/index.php?r=home%2Fdownload&relativePath={the relative path of the file}
* *
* @param string $relativePath 文件的相对路径 * @param string $relativePath 文件的相对路径
@ -99,4 +121,111 @@ class HomeController extends \yii\web\Controller
// 将文件发送给用户进行下载 // 将文件发送给用户进行下载
Yii::$app->response->sendFile($realPath)->send(); Yii::$app->response->sendFile($realPath)->send();
} }
/**
* 重命名文件或文件夹
* @param string $relativePath 文件或文件夹的相对路径
* @param string $newName 新名称
* @throws NotFoundHttpException 如果文件或文件夹不存在
*/
public function actionRename()
{
$relativePath = Yii::$app->request->post('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;
// 检查文件或文件夹是否存在
if (!file_exists($absolutePath)) {
throw new NotFoundHttpException('File or directory not found.');
}
$model = new RenameForm();
$model->newName = ArrayHelper::getValue(Yii::$app->request->post('RenameForm'), 'newName');
if (!$model->validate()) {
Yii::$app->response->statusCode = 400;
return $model->getFirstError('newName');
}
// 检查新名称是否和现有的文件或文件夹重名
if (file_exists(dirname($absolutePath) . '/' . $model->newName)) {
Yii::$app->session->setFlash('error', 'Failed to rename file or directory.');
return $this->redirect(['index', 'directory' => dirname($relativePath)]);
}
// 重命名文件或文件夹
if (!rename($absolutePath, dirname($absolutePath) . '/' . $model->newName)) {
Yii::$app->session->setFlash('error', 'Failed to rename file or directory.');
} else {
Yii::$app->session->setFlash('success', 'File or directory renamed successfully.');
}
return $this->redirect(['index', 'directory' => dirname($relativePath)]);
}
/**
* 删除文件或文件夹
* @param string $relativePath 文件或文件夹的相对路径
* @throws NotFoundHttpException 如果文件或文件夹不存在
*/
public function actionDelete($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;
// 检查文件或文件夹是否存在
if (!file_exists($absolutePath)) {
throw new NotFoundHttpException('File or directory not found.');
}
// 删除文件或文件夹
if (is_dir($absolutePath)) {
// 如果是文件夹,递归删除文件夹及其内容
$this->deleteDirectory($absolutePath);
} else {
// 如果是文件,直接删除文件
$fileinfo = $absolutePath; //要删了,准备一下
$fileinfo2 = $fileinfo;
//unlink($absolutePath);
}
}
/**
* 递归删除目录及其内容
* @param string $dir 目录路径
*/
protected function deleteDirectory($dir)
{
if (!is_dir($dir)) {
return;
}
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$dir1 = $dir;
$file1 = $file;
$file2 = $file1;
is_dir("$dir/$file") ? $this->deleteDirectory("$dir/$file") : ''; //unlink("$dir/$file");
}
$dir1 = $dir;
$dir2 = $dir1;
rmdir($dir);
}
} }

View File

@ -3,14 +3,24 @@
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $directoryContents array 文件和文件夹内容数组 */ /* @var $directoryContents array 文件和文件夹内容数组 */
/* @var $parentDirectory string 父目录 */ /* @var $parentDirectory string 父目录 */
/* @var $directory string 当前路径 */ /* @var $directory string 当前路径 */
use app\models\RenameForm;
use yii\bootstrap5\ActiveForm;
use yii\bootstrap5\Html; use yii\bootstrap5\Html;
use app\assets\FontAwesomeAsset; use app\assets\FontAwesomeAsset;
use yii\bootstrap5\Modal;
use yii\helpers\Url;
use yii\web\JqueryAsset;
use yii\web\View;
$this->title = '文件管理'; $this->title = '文件管理';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
FontAwesomeAsset::register($this); FontAwesomeAsset::register($this);
JqueryAsset::register($this);
$this->registerCssFile('@web/css/home_style.css');
?> ?>
<div class="home-directory"> <div class="home-directory">
<h1><?= Html::encode($this->title) ?></h1> <h1><?= Html::encode($this->title) ?></h1>
@ -48,20 +58,61 @@ FontAwesomeAsset::register($this);
<?php if (is_dir($absolutePath)): ?> <?php if (is_dir($absolutePath)): ?>
<!-- 文件夹 --> <!-- 文件夹 -->
<td> <td>
<?= Html::tag('i', '', ['class' => $item['type']]) ?> <?= Html::tag('i', '', ['class' => $item['type'] . ' file_icon']) ?>
<?= Html::a($item['name'], ['home/index', 'directory' => $relativePath]) ?> <?= Html::a($item['name'], ['home/index', 'directory' => $relativePath], ['class' => 'file_name']) ?>
</td>
<td>
<?= Html::button(Html::tag('i', '', ['class' => 'fa-regular fa-pen-to-square']), ['value' => $relativePath, 'class' => 'btn btn-outline-secondary rename-btn']) ?>
</td> </td>
<td></td>
<?php else: ?> <?php else: ?>
<!-- 文件 --> <!-- 文件 -->
<td> <td>
<?= Html::tag('i', '', ['class' => $item['type']]) ?> <?= Html::tag('i', '', ['class' => $item['type'] . ' file_icon']) ?>
<?= Html::a($item['name'], ['home/download', 'relativePath' => $relativePath]) ?> <?= Html::a($item['name'], ['home/download', 'relativePath' => $relativePath], ['class' => 'file_name']) ?>
</td>
<td>
<?= Html::button(Html::tag('i', '', ['class' => 'fa-regular fa-circle-down']), [
'value' => Url::to(['home/download', 'relativePath' => $relativePath]),
'class' => 'btn btn-outline-primary download-btn'
]) ?>
<?= Html::button(Html::tag('i', '', ['class' => 'fa-regular fa-pen-to-square']), ['value' => $relativePath, 'class' => 'btn btn-outline-secondary rename-btn']) ?>
</td> </td>
<td><?= Html::a(Html::tag('i', '', ['class' => 'fa-regular fa-circle-down']), ['home/download', 'relativePath' => $relativePath]) ?></td>
<?php endif; ?> <?php endif; ?>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
</div> </div>
<?php
Modal::begin([
'title' => '<h4>重命名文件/文件夹</h4>',
'id' => 'renameModal',
'size' => 'modal-lg',
]);
$model = new RenameForm();
$form = ActiveForm::begin(['id' => 'rename-form', 'action' => ['home/rename'], 'method' => 'post']);
echo $form->field($model, 'newName')->textInput(['maxlength' => true])->label('新名称');
echo Html::hiddenInput('relativePath', '', ['id' => 'renameRelativePath']);
echo Html::submitButton('提交', ['class' => 'btn btn-primary']);
ActiveForm::end();
Modal::end();
$this->registerJs(
"$(document).on('click', '.rename-btn', function() {
var relativePath = $(this).attr('value');
var fileName = $(this).closest('tr').find('td:first').text().trim();
$('#renameRelativePath').val(relativePath);
$('#renameform-newname').val(fileName);
$('#renameModal').modal('show');
})
.on('click', '.download-btn', function() {
window.location.href = $(this).attr('value');
});",
View::POS_READY,
'button-handlers'
);
?>

17
web/css/home_style.css Normal file
View File

@ -0,0 +1,17 @@
table a {
text-decoration-line: none;
}
.file_icon {
font-size: xx-large;
vertical-align: middle;
width: 34px;
text-align: center;
}
.file_name {
font-size: large;
margin-left: 0.3em;
vertical-align: middle;
line-height: 2;
}