From 2b82d108c07f3b00eebffb70d783449822c96587 Mon Sep 17 00:00:00 2001 From: filesite Date: Thu, 13 Oct 2022 12:07:42 +0800 Subject: [PATCH] api/uploadbase64 done, fix DirScanner's bug to support php 5.6 --- conf/app.php | 19 ++++-- controller/ApiController.php | 116 ++++++++++++++++++++++++++++++++--- controller/Controller.php | 8 +++ lib/DirScanner.php | 10 ++- www/img/default.png | Bin 0 -> 2737 bytes 5 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 www/img/default.png 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 0000000000000000000000000000000000000000..46e30f9f573e8a9a6910c87a47c40bf81cad87be GIT binary patch literal 2737 zcmbVOdpK0<9{$#>u?#abF12TH7>pX(Wn4pKguPMh*=SQX4GQfdB#}#tB$twI+fHO$ zVqC}lIvAPggxGE=Z1(6PIZB(&7CNi5pYzvw&T}rmXFcEV{oe2QzQ6BV-}+-Evz@+{ zkyerh0La+e**F7$!ypb2U@UbO(jR?J?1QehSZ-`=6bglfg@x_y?e+EbwY9Y!9Ub}k z`SfGF1Y$-cCJ1;Mf%jMS9)$#d!fk04DP=Jk?u&u4Fyu2J6TUuH$hnkw2 zii(QT($YVLO-)T$i-v}V%F0Tt81ux6i;IhSJRatN#r^yDTmKQw&COVMOpZ0h(0pHjgDida=`U*3z9Wi;-6mw{PZ^T+=GSU23H2|c% z>}{-EBc9K9#9_Vwra9NWyi57~Y&; zxlkIi;3t1e^{wNI*OWn7t>e(9g+a zkdc+1ZpCl~{$W<5^Iby9;TC5FMZ=K$+ZnUHw=+?|0yIDd1c1kG9s0M^5}5D~htHh^ zenlo0+0SLTucjxug1}bE*H5H`#yDmgxS|PW2tt$p9&(R~Lx!o{c#a<06M67Neq}soC))74E#nh`|2zuER1n6xTZC0k-2eyi+0is1k3Iow?OGYrnZOVs zw>mgw$UzJeSEFf!z&Z*}``_@Wrh`DpyjNtM3Th<=WFA_dwFi%JW62qRfo7$-*ON2K zoInX~77@R`1zaVV^54YZ*jrf#%TR~rODU9h|72XcTJx^^?-{COHy+87sM_S!bR1bB&th!9VjtDKUv8_Tp< zMcu;=SkqvSMdz7|A~CBDirT8(e}ZRrJ$_PV+R+(4-4Z3I&RJD5!JZIDlQfk|3f(PD(5N5U zH}UDvvd!K+tFig*^1uJ#38Me#f03QNN7)l9P=#n!@>L>m>;7VQjGIUfW{-4t(SN*2 zgW0t_aSqW;5)mQWNw$arKT}nqmEFGIBUT6*jk(;q+b48; zFL?3t$1$zg9*D&9QoS53u2K<#g7Whwc9H5nDDg+ih3}QD>Rk4h zMs96)tRc~wL5dN6&vL?7w=ZaW9jCHfp(}4sG9D2FyCT;!R1DB0TmUQX$xC#Cq+4Kt zknKT+6t6ffVOzOby?F$Q77vbS@k;6vkZ@&wm^nf|4`#H7M?7;+EgIYC^n?9drpJ|( z!V*fXMplgI2ssp!&jybw{;)<}ePcvn@t}eq*hR5t(3Ka$92ak(j!Zk|9_ZT^cXeo6 zc+-Lb`X0w~AMksVf;yiSX#RW*cuNG|i_>4ecvrkbpkv?t+cN;ToWu)M1{kWbKdXA(lR14QJ9%qn{&&{Iq}%b?`*E zI_R+GegpfzG_UKF9y0(IP=o>R+oQ7Xhc4D0Hvqe!rCkhc%A=D-zSp4u0>{;smsL2X zsa7itzYg&vxcdNR-Z=G?Fz1pA@sRXH>E*j{8>2Px{Tm|8CUPSa(_23U<;3K#4rwD? zc_Hr#p=`+KGT(@?mgNgN;74_G$!Bd>l_sp74Ic+_u$`vHW)IYdH*5^0vVPMb9tnVqY;_pCcRMv{>w=K%aSG}Rk@^(FR@`l|I3$ zIwakv(jMwwJ((aZVS)>>P%nQ`ZZuL|kamfkwM-Sto>)xr?CK8Ae5UkVDW zSY?cSo$&h96A-QSuwLzCR-q{C8VcjwJ!f2RyOB7jK{!-YYR&;sxZn(v<0I;Dge7Y3 zG`^t)N9dw)7Zu!0`~jaXLj}eTM5Iy&o!>=bE9;@V?0pgRYGxmZhADJTVloDB3?(Kw zWnNDa-UZcXf6Cvu1PNrPrM90aq6ou5=S@p!Ec~Vq(1jVJoS%-TL8oxcKrq(Wr-y!m z3^`n42F6e_LvfXXbNZ+yq6rhI@UA`dk zpO59U7GD)y9!SY+S4d8(g!0(x-v;=9YN?jAUOdx(xU+mJRe_ZS#CY-!)C3Yq(VRdC zF6lo|+1S_||){r9{- nu|?MIvjV?yVe%ULU&Pb8F{V*b?fR=dpNs5moop)hbK?IF=s0Jp literal 0 HcmV?d00001