Skip to content

Commit 4cd82b9

Browse files
committed
upload and remote download done
1 parent 04447fa commit 4cd82b9

File tree

6 files changed

+168
-12
lines changed

6 files changed

+168
-12
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"symfony/filesystem": "^5.0",
1515
"symfony/finder": "^5.0",
1616
"symfony/http-foundation": "^5.0",
17-
"symfony/error-handler": "^5.0"
17+
"symfony/error-handler": "^5.0",
18+
"symfony/mime": "^5.0",
19+
"ext-json": "*"
1820
},
1921
"autoload": {
2022
"psr-4": {

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/FileManager.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function __construct()
2424
private function preventJailBreak()
2525
{
2626
$path = base_path(request('path'));
27+
2728
if ( ! $path) {
2829
abort(403);
2930
}

src/Plugins/General.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Rocky\FileManager\Plugins;
44

55
use Symfony\Component\Finder\SplFileInfo;
6+
use Symfony\Component\HttpFoundation\File\File;
7+
use Symfony\Component\HttpFoundation\File\UploadedFile;
68
use Symfony\Component\HttpFoundation\Response;
79

810
class General
@@ -173,4 +175,48 @@ private function recursive_delete($target)
173175

174176
filesystem()->remove($target);
175177
}
178+
179+
/**
180+
* @return Response|null
181+
*/
182+
public function upload()
183+
{
184+
/** @var UploadedFile $file */
185+
$file = request()->files->get('file');
186+
$file->move(request_path(), $file->getClientOriginalName());
187+
188+
$filepath = absolutePath(request_path(), $file->getClientOriginalName());
189+
190+
if (filesystem()->exists($filepath)) {
191+
return jsonResponse(['message' => 'File upload successful']);
192+
}
193+
194+
return jsonResponse(['message' => 'Could not move uploaded file'], 500);
195+
}
196+
197+
/**
198+
* @return Response|null
199+
*/
200+
public function remote_download()
201+
{
202+
$url = request('url');
203+
$name = pathinfo($url, PATHINFO_FILENAME);
204+
$ext = pathinfo($url, PATHINFO_EXTENSION);
205+
206+
$filepath = getSafePath($name, $ext);
207+
208+
filesystem()->copy($url, $filepath);
209+
210+
if ( ! filesystem()->exists($filepath)) {
211+
return jsonResponse(['message' => 'Could not download remote file'], 500);
212+
}
213+
214+
$mime = ensureSafeFile($filepath);
215+
$ext = mimeTypes()->getExtensions($mime)[0];
216+
$new_path = getSafePath($name, $ext);
217+
filesystem()->rename($filepath, $new_path);
218+
219+
$relative_path = substr($new_path, strlen(base_path()));
220+
return jsonResponse(['message' => 'The file has been downloaded', 'file' => $relative_path]);
221+
}
176222
}

src/config.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<?php
22

33
return [
4-
'root' => __DIR__.'/../storage/',
4+
'root' => __DIR__.'/../storage/',
5+
'uploads' => [
6+
'allowed_types' => [
7+
'image/jpeg', 'image/png', 'image/gif', 'image/bmp',
8+
]
9+
]
510
];

src/helpers.php

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use Symfony\Component\Finder\Finder;
55
use Symfony\Component\HttpFoundation\Request;
66
use Symfony\Component\HttpFoundation\Response;
7+
use Symfony\Component\Mime\MimeTypes;
78

89
$container = [];
910

@@ -98,6 +99,19 @@ function jsonResponse($array, $code = 200)
9899
return $response;
99100
}
100101

102+
/**
103+
* @return MimeTypes
104+
*/
105+
function mimeTypes()
106+
{
107+
global $container;
108+
if ( ! isset($container['mime_types'])) {
109+
$container['mime_types'] = new MimeTypes();
110+
}
111+
112+
return $container['mime_types'];
113+
}
114+
101115
/**
102116
* @return Finder
103117
*/
@@ -120,26 +134,65 @@ function filesystem()
120134
}
121135

122136
/**
123-
* @param $key
137+
* @param $path
124138
* @param mixed $value
125139
*
126140
* @return mixed|null
127141
*/
128-
function config($key, $value = null)
142+
function config($path, $value = null)
129143
{
130144
global $container;
131145
if ( ! isset($container['config'])) {
132146
$container['config'] = include __DIR__.'/config.php';
133147
}
134148
if ( ! $value) {
135-
if (isset($container['config'][$key])) {
136-
return $container['config'][$key];
149+
return getConfig($path);
150+
} else {
151+
return setConfig($path, $value);
152+
}
153+
}
154+
155+
/**
156+
* @param $path
157+
*
158+
* @return null
159+
*/
160+
function getConfig($path)
161+
{
162+
global $container;
163+
$cf = $container['config'];
164+
$_path = explode('.', $path);
165+
foreach ($_path as $_p) {
166+
if (isset($cf[$_p])) {
167+
$cf = $cf[$_p];
137168
} else {
138169
return null;
139170
}
140-
} else {
141-
return $container['config'][$key] = $value;
142171
}
172+
173+
return $cf;
174+
}
175+
176+
/**
177+
* @param $path
178+
* @param $value
179+
*
180+
* @return null
181+
*/
182+
function setConfig($path, $value)
183+
{
184+
global $container;
185+
$cf = &$container['config'];
186+
$_path = explode('.', $path);
187+
$last = array_pop($_path);
188+
foreach ($_path as $_p) {
189+
if (isset($cf[$_p])) {
190+
$cf = &$cf[$_p];
191+
} else {
192+
return null;
193+
}
194+
}
195+
$cf[$last] = $value;
143196
}
144197

145198
/**
@@ -173,10 +226,11 @@ function endsWith($haystack, $needle)
173226

174227
/**
175228
* @param $code
229+
* @param array $data
176230
*/
177-
function abort($code)
231+
function abort($code, $data = ['message' => 'Aborted'])
178232
{
179-
$response = jsonResponse(['message' => 'Aborted']);
233+
$response = jsonResponse($data);
180234
$response->setStatusCode($code);
181235
$response->prepare(request())->send();
182236
die;
@@ -204,4 +258,52 @@ function getFileInfo(\Symfony\Component\Finder\SplFileInfo $file)
204258
'extension' => $file->getExtension(),
205259
'type' => $file->getType(),
206260
];
207-
}
261+
}
262+
263+
/**
264+
* @param $name
265+
* @param string $ext
266+
*
267+
* @return string|string[]|null
268+
*/
269+
function getSafePath($name, $ext = '')
270+
{
271+
$filepath = sanitizePath(request_path().'/'.$name);
272+
if ($ext !== '') {
273+
$filepath .= '.'.$ext;
274+
}
275+
$i = 1;
276+
while (filesystem()->exists($filepath)) {
277+
$filepath = sanitizePath(request_path().'/'.$name.'('.($i++).')');
278+
if ($ext !== '') {
279+
$filepath .= '.'.$ext;
280+
}
281+
}
282+
283+
return $filepath;
284+
}
285+
286+
/**
287+
* @param $filepath
288+
*
289+
* @return string|Response|null
290+
*/
291+
function ensureSafeFile($filepath)
292+
{
293+
$mime = mimeTypes()->guessMimeType($filepath);
294+
$valid = false;
295+
foreach (config('uploads.allowed_types') as $allowed_type) {
296+
if (preg_match("#^{$allowed_type}$#", $mime)) {
297+
$valid = true;
298+
break;
299+
}
300+
}
301+
302+
if ( ! $valid) {
303+
filesystem()->remove($filepath);
304+
305+
abort(403, ['message' => 'This type of file is not allowed to be downloaded or uploaded']);
306+
}
307+
308+
return $mime;
309+
}

0 commit comments

Comments
 (0)