diff --git a/conf/app.php b/conf/app.php index c84836e..652dcf6 100644 --- a/conf/app.php +++ b/conf/app.php @@ -15,13 +15,14 @@ return array( //'theme' => 'webdirectory', //图片站皮肤 - //'content_directory' => 'girls/', //directory of contents in /www/ - //'theme' => 'googleimage', //name of theme which is enabled + 'content_directory' => 'girls/', //directory of contents in /www/ + 'theme' => 'googleimage', //name of theme which is enabled //视频站皮肤 - 'content_directory' => 'videos/', //directory of contents in /www/ - 'theme' => 'videoblog', //name of theme which is enabled - + //'content_directory' => 'videos/', //directory of contents in /www/ + //'theme' => 'videoblog', //name of theme which is enabled + + 'maxScanDirLevels' => 4, //max directory levels to scan 'default_layout' => 'main', //default layout 'error_layout' => 'error', //exception layout, show error title and content @@ -51,6 +52,14 @@ return array( 'username' => 'filesite', 'password' => '88888888', 'captcha' => true, //后台登陆是否开启验证码 + + 'maxUploadFileSize' => 20, //单位:Mb + 'allowedUploadFileTypes' => array( + 'image/jpeg', + 'image/png', + 'image/webp', + 'image/gif', + ), ), ); diff --git a/controller/ApiController.php b/controller/ApiController.php index 9e50589..5a0c2b0 100644 --- a/controller/ApiController.php +++ b/controller/ApiController.php @@ -52,7 +52,7 @@ Class ApiController extends Controller { $scanner = new DirScanner(); $scanner->setWebRoot(FSC::$app['config']['content_directory']); $target = __DIR__ . '/../www/' . FSC::$app['config']['content_directory']; - $maxLevels = 2; + $maxLevels = FSC::$app['config']['maxScanDirLevels']; $dirTree = $scanner->scan($target, $maxLevels); $scanResults = $scanner->getScanResults(); @@ -126,12 +126,6 @@ Class ApiController extends Controller { try { $res = mkdir("{$target}/{$newDir}"); if ($res) { - //读取父目录数据,并返回包含新建的子目录在内的新数据 - $scanner = new DirScanner(); - $scanner->setWebRoot(FSC::$app['config']['content_directory']); - $maxLevels = 2; - $data = $scanner->scan($target, $maxLevels); - $code = 1; $msg = '目录创建完成'; }else { @@ -455,4 +449,112 @@ Class ApiController extends Controller { return $logined; } + //保存base64格式的文件 + protected function saveBase64File($base64FileContent, $filePath) { + $saved = true; + + try { + $base64 = preg_replace('/^data:[a-z0-9]+\/[a-z0-9]+;base64,/i', '', $base64FileContent); + $base64 = str_replace(' ', '+', $base64); + $fileContent = base64_decode($base64); + file_put_contents($filePath, $fileContent); + }catch(Exception $e) { + $saved = false; + } + + return $saved; + } + + //在指定目录里创建一个新文件 + //@fileType 示例:image/jpeg, video/mp4 + protected function createNewFile($parentDir, $filename) { + $target = __DIR__ . '/../www/' . FSC::$app['config']['content_directory']; + return !empty($parentDir) ? "{$target}{$parentDir}/{$filename}" : "{$target}{$filename}"; + } + + //从文件名中解析文件后缀 + protected function getSuffixFromFilename($filename) { + $arr = explode('.', $filename); + if (count($arr) < 2) { + return ''; + } + + return strtolower(array_pop($arr)); + } + + //从文件类型中解析文件后缀 + protected function getSuffixFromFileType($fileType) { + $arr = explode('/', $fileType); + if (count($arr) < 2) { + return ''; + } + + $suffix = array_pop($arr); + if (in_array($suffix, ['jpg', 'jpeg'])) { + $suffix = 'jpg'; + } + + return strtolower($suffix); + } + + //base64格式文件上传 + //@parent - 可选:文件保存目录,默认保存到根目录 + //@file - 单个文件base64内容 + //@name - 单个文件文件名 + public function actionUploadBase64() { + $code = 0; + $msg = $err = ''; + $data = array(); + + if ($this->isUserLogined() == false) { + $err = '没登陆或登陆已过期!'; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notLogined']); + } + + //参数检查 + $parentDir = $this->post('parent', ''); + $upfile = $this->post('file', ''); + $filename = $this->post('name', ''); + if (empty($upfile) || empty($filename)) { + $err = '所有参数都不能为空!'; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notLogined']); + }else if (!preg_match('/^data:[a-z0-9]+\/[a-z0-9]+;base64,/i', $upfile)) { + $err = '图片数据必需为base64格式!'; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notLogined']); + } + + //base64格式数据支持 + $configs = FSC::$app['config']['admin']; + try { + preg_match('/^data:([a-z0-9]+\/[a-z0-9]+);base64,/i', $upfile, $matches); + if (!empty($matches[1])) { + $fileType = strtolower($matches[1]); + if (strpos($filename, '.') === false) {$filename .= "." . $this->getSuffixFromFileType($fileType);} + + if (!in_array($fileType, $configs['allowedUploadFileTypes'])) { + $err = "不支持的文件格式:{$fileType}"; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); + }else if ($this->getSuffixFromFilename($filename) != $this->getSuffixFromFileType($fileType)) { + $err = "文件格式和文件名后缀不匹配,请检查文件名后缀"; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); + } + + $filePath = $this->createNewFile($parentDir, $filename); + if ($this->saveBase64File($upfile, $filePath)) { + $code = 1; + $msg = '上传完成'; + }else { + $err = '上传失败,请检查数据目录权限配置!'; + } + }else { + $err = "文件数据不是base64格式"; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); + } + }catch(Exception $e) { + $err = $e->getMessage(); + } + + return $this->renderJson(compact('code', 'msg', 'err', 'data')); + } + } diff --git a/controller/Controller.php b/controller/Controller.php index 9c3aa81..b704d20 100644 --- a/controller/Controller.php +++ b/controller/Controller.php @@ -277,4 +277,12 @@ Class Controller { return compact('menus', 'dirTree'); } + //get basename of realpath, support chinese + protected function basename($realpath) { + $arr = explode('/', $realpath); + if (count($arr) < 2) {return $realpath;} + + return array_pop($arr); + } + } diff --git a/lib/DirScanner.php b/lib/DirScanner.php index 23caa66..13f55a7 100644 --- a/lib/DirScanner.php +++ b/lib/DirScanner.php @@ -159,12 +159,20 @@ Class DirScanner { return $valid; } + //获取路径中的最后一个目录名,支持中文 + private function basename($realpath) { + $arr = explode('/', $realpath); + if (count($arr) < 2) {return $realpath;} + + return array_pop($arr); + } + //根据路径生成目录数组 private function getDirData($realpath, $files) { $id = $this->getId($realpath); $data = array( 'id' => $id, - 'directory' => basename($realpath), + 'directory' => $this->basename($realpath), 'realpath' => $realpath, 'path' => $this->getDirPath($id), ); diff --git a/www/img/default.png b/www/img/default.png new file mode 100644 index 0000000..46e30f9 Binary files /dev/null and b/www/img/default.png differ