新增功能 新建文件夹、刷新

修复了一些奇怪的逻辑问题
不得不说,有些地方传参数 压根没传进模型,都是后期补进去或直接就在外面操作了
This commit is contained in:
Chenx221 2024-02-14 21:35:54 +08:00
parent aff1662ccc
commit a845774163
Signed by: chenx221
GPG Key ID: D7A9EC07024C3021
4 changed files with 139 additions and 23 deletions

View File

@ -2,10 +2,12 @@
namespace app\controllers; namespace app\controllers;
use app\models\NewFolderForm;
use app\models\RenameForm; use app\models\RenameForm;
use app\models\UploadForm; use app\models\UploadForm;
use app\utils\FileTypeDetector; use app\utils\FileTypeDetector;
use Yii; use Yii;
use yii\bootstrap5\ActiveForm;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\web\Controller; use yii\web\Controller;
@ -30,6 +32,8 @@ class HomeController extends Controller
'rename' => ['POST'], 'rename' => ['POST'],
'delete' => ['POST'], 'delete' => ['POST'],
'upload' => ['POST'], 'upload' => ['POST'],
'newfolder' => ['POST'],
'checkfolderexists' => ['POST'],
], ],
], ],
] ]
@ -260,7 +264,7 @@ class HomeController extends Controller
} }
/** /**
* 文件上传 * 文件、文件夹上传
* 注意,已存在的同名文件会被覆盖 * 注意,已存在的同名文件会被覆盖
* https://devs.chenx221.cyou:8081/index.php?r=home%2Fupload * https://devs.chenx221.cyou:8081/index.php?r=home%2Fupload
* *
@ -276,7 +280,7 @@ class HomeController extends Controller
foreach ($uploadedFiles as $uploadedFile) { foreach ($uploadedFiles as $uploadedFile) {
$model->uploadFile = $uploadedFile; $model->uploadFile = $uploadedFile;
if (!preg_match($this->pattern, $model->uploadFile->fullPath)) { if (!preg_match($this->pattern, $model->uploadFile->fullPath) || $model->uploadFile->fullPath === '.' || $model->uploadFile->fullPath === '..' || str_contains($model->uploadFile->fullPath, '../')) {
continue; continue;
} }
if ($model->upload()) { if ($model->upload()) {
@ -294,4 +298,39 @@ class HomeController extends Controller
//返回状态码200 //返回状态码200
return Yii::$app->response->statusCode = 200; // 如果出错请删掉return return Yii::$app->response->statusCode = 200; // 如果出错请删掉return
} }
/**
* @return array|string|Response
*/
public function actionNewfolder()
{
$relativePath = Yii::$app->request->post('relativePath');
$relativePath = rawurldecode($relativePath);
$model = new NewFolderForm();
if ($model->load(Yii::$app->request->post())){
$model->relativePath = $relativePath;
if(Yii::$app->request->isAjax){
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if($model->validate()){
if ($model->createFolder()) {
Yii::$app->session->setFlash('success', 'Folder created successfully.');
} else {
Yii::$app->session->setFlash('error', 'Failed to create folder.');
}
} else {
$errors = $model->errors;
foreach ($errors as $error) {
Yii::$app->session->setFlash('error', $error[0]);
}
}
}
return $this->redirect(['index', 'directory' => $relativePath]);
}
} }

48
models/NewFolderForm.php Normal file
View File

@ -0,0 +1,48 @@
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class NewFolderForm extends Model
{
public $folderName;
public $relativePath; // 要在哪里新建文件夹的路径
public function rules()
{
return [
['folderName', 'required'],
['folderName', 'string', 'max' => 255],
['folderName', 'match', 'pattern' => '/^[^\p{C}:*?"<>\/|\\\\]+$/u', 'message' => 'Folder name contains invalid characters.'],
['folderName', 'validateFolderName'],
['relativePath', 'match', 'pattern' => '/^[^\p{C}:*?"<>|\\\\]+$/u', 'message' => 'Path contains invalid characters.'],
['relativePath', 'validateRelativePath'],
];
}
public function validateRelativePath($attribute, $params, $validator)
{
if (str_contains($this->$attribute, '../') || str_contains($this->$attribute, '..')) {
$this->addError($attribute, 'Invalid file path.');
}
}
public function validateFolderName($attribute, $params, $validator)
{
$userHomeDir = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id;
$absolutePath = $userHomeDir . '/' . $this->relativePath . '/' . $this->$attribute;
if (file_exists($absolutePath)) {
$this->addError($attribute, 'Folder name already exists.');
}
}
public function createFolder()
{
$userHomeDir = Yii::getAlias(Yii::$app->params['dataDirectory']) . '/' . Yii::$app->user->id;
$absolutePath = $userHomeDir . '/' . $this->relativePath . '/' . $this->folderName;
return mkdir($absolutePath, 0777);
}
}

View File

@ -6,6 +6,7 @@
/* @var $directory string 当前路径 */ /* @var $directory string 当前路径 */
use app\models\NewFolderForm;
use app\models\RenameForm; use app\models\RenameForm;
use yii\bootstrap5\ActiveForm; use yii\bootstrap5\ActiveForm;
use yii\bootstrap5\Html; use yii\bootstrap5\Html;
@ -26,26 +27,30 @@ $this->registerCssFile('@web/css/home_style.css');
<div class="home-directory"> <div class="home-directory">
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<h1><?= Html::encode($this->title) ?></h1> <h1><?= Html::encode($this->title) ?></h1>
<div class="dropdown"> <div>
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" <?= Html::button('刷新', ['class' => 'btn btn-outline-primary refresh-btn']) ?>
data-bs-toggle="dropdown" aria-expanded="false"> <?= Html::button('新建文件夹', ['class' => 'btn btn-outline-primary new-folder-btn', 'value' => $directory]) ?>
<i class="fa-solid fa-arrow-up-from-bracket"></i> 上传文件 <div class="dropdown d-inline-block">
</button> <button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton"
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton"> data-bs-toggle="dropdown" aria-expanded="false">
<li hidden> <i class="fa-solid fa-arrow-up-from-bracket"></i> 上传文件
<input type="file" id="file-input" name="uploadFile" multiple> </button>
<input type="file" id="folder-input" name="uploadFile" multiple webkitdirectory> <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<input type="hidden" name="targetDir" value="<?= $directory ?>" id="target-dir"> <li hidden>
</li> <input type="file" id="file-input" name="uploadFile" multiple>
<li><?= Html::button('上传文件', ['class' => 'dropdown-item file-upload-btn']) ?></li> <input type="file" id="folder-input" name="uploadFile" multiple webkitdirectory>
<!-- 上传文件功能将会覆盖已存在的同名文件,这点请注意--> <input type="hidden" name="targetDir" value="<?= $directory ?>" id="target-dir">
<li><?= Html::button('上传文件夹', ['class' => 'dropdown-item folder-upload-btn']) ?></li> </li>
<!-- 上传文件夹功能不支持IOS设备以及Firefox for Android上传时会跳过空文件夹--> <li><?= Html::button('上传文件', ['class' => 'dropdown-item file-upload-btn']) ?></li>
<li> <!-- 上传文件功能将会覆盖已存在的同名文件,这点请注意-->
<hr class="dropdown-divider"> <li><?= Html::button('上传文件夹', ['class' => 'dropdown-item folder-upload-btn']) ?></li>
</li> <!-- 上传文件夹功能不支持IOS设备以及Firefox for Android上传时会跳过空文件夹-->
<li><?= Html::button('离线下载', ['class' => 'dropdown-item offline-download-btn']) ?></li> <li>
</ul> <hr class="dropdown-divider">
</li>
<li><?= Html::button('离线下载', ['class' => 'dropdown-item offline-download-btn']) ?></li>
</ul>
</div>
</div> </div>
</div> </div>
@ -176,6 +181,23 @@ echo Html::submitButton('确认', ['class' => 'btn btn-danger']);
echo Html::endForm(); echo Html::endForm();
Modal::end(); Modal::end();
Modal::begin([
'title' => '<h4>新建文件夹</h4>',
'id' => 'newFolderModal',
'size' => 'modal-lg',
]);
$model1 = new NewFolderForm();
$form = ActiveForm::begin(['id' => 'new-folder-form', 'action' => ['home/newfolder'], 'method' => 'post', 'enableAjaxValidation' => true]);
echo $form->field($model1, 'folderName')->textInput(['maxlength' => true])->label('文件夹名称 (受技术所限暂时没什么办法通过js验证文件夹是否已存在以在client side显示)');
echo Html::hiddenInput('relativePath', '', ['id' => 'newDirRelativePath']);
echo Html::submitButton('提交', ['class' => 'btn btn-primary']);
ActiveForm::end();
Modal::end();
$this->registerJsFile('@web/js/home_script.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]); $this->registerJsFile('@web/js/home_script.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]);
?> ?>

View File

@ -120,5 +120,12 @@ dropArea.addEventListener('dragleave', function (event) {
} }
}); });
$(document).on('click', '.refresh-btn', function () {
window.location.reload();
});
$(document).on('click', '.new-folder-btn', function () {
var relativePath = $(this).attr('value');
$('#newDirRelativePath').val(relativePath);
$('#newFolderModal').modal('show');
})