Passed
Push — master ( 7619d4...4e692e )
by Jianhua
04:42
created

NEditorController   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 260
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 145
c 1
b 0
f 0
dl 0
loc 260
rs 9.28
wmc 39

11 Methods

Rating   Name   Duplication   Size   Complexity  
A catchImage() 0 27 6
A uploadImage() 0 34 5
A isAllowedImageType() 0 5 1
A uploadVideo() 0 34 5
A serve() 0 10 2
A isValidVideo() 0 9 1
B fetchImageFile() 0 38 7
A isValidImage() 0 9 1
A uploadFile() 0 34 5
A isValidFile() 0 9 1
A isValidUploadedFile() 0 17 5
1
<?php
2
/**
3
 * Date: 2019/3/16 Time: 13:42
4
 *
5
 * @author  Eddy <[email protected]>
6
 * @version v1.0.0
7
 */
8
9
namespace App\Http\Controllers\Admin;
10
11
use App\Http\Controllers\Controller;
12
use Illuminate\Http\Request;
13
use Illuminate\Http\UploadedFile;
14
use Illuminate\Support\Facades\Storage;
15
use Intervention\Image\Facades\Image;
16
use Intervention\Image\Exception\NotReadableException;
17
18
class NEditorController extends Controller
19
{
20
    /**
21
     * 基础功能-图片上传
22
     *
23
     * @param Request $request
24
     * @param string $type
25
     * @return array
26
     */
27
    public function serve(Request $request, $type)
28
    {
29
        if (!method_exists(self::class, $type)) {
30
            return [
31
                'code' => 1,
32
                'msg' => '未知操作'
33
            ];
34
        }
35
36
        return call_user_func(self::class . '::' . $type, $request);
37
    }
38
39
    protected function uploadImage(Request $request)
40
    {
41
        if (config('light.image_upload.driver') !== 'local') {
42
            $class = config('light.image_upload.class');
43
            return call_user_func([new $class, 'uploadImage'], $request);
44
        }
45
46
        if (!$request->hasFile('file')) {
47
            return [
48
                'code' => 2,
49
                'msg' => '非法请求'
50
            ];
51
        }
52
        $file = $request->file('file');
53
        if (!$this->isValidImage($file)) {
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type Illuminate\Http\UploadedFile[] and array and null; however, parameter $file of App\Http\Controllers\Adm...troller::isValidImage() does only seem to accept Illuminate\Http\UploadedFile, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
        if (!$this->isValidImage(/** @scrutinizer ignore-type */ $file)) {
Loading history...
54
            return [
55
                'code' => 3,
56
                'msg' => '文件不合要求'
57
            ];
58
        }
59
60
        $result = $file->store(date('Ym'), config('light.neditor.disk'));
61
        if (!$result) {
62
            return [
63
                'code' => 3,
64
                'msg' => '上传失败'
65
            ];
66
        }
67
68
        return [
69
            'code' => 200,
70
            'state' => 'SUCCESS', // 兼容ueditor
71
            'msg' => '',
72
            'url' => Storage::disk(config('light.neditor.disk'))->url($result),
73
        ];
74
    }
75
76
    public function catchImage(Request $request)
77
    {
78
        if (config('light.image_upload.driver') !== 'local') {
79
            $class = config('light.image_upload.class');
80
            return call_user_func([new $class, 'catchImage'], $request);
81
        }
82
83
        $files = array_unique((array) $request->post('file'));
84
        $urls = [];
85
        foreach ($files as $v) {
86
            $image = $this->fetchImageFile($v);
87
            if (!$image || !$image['extension'] || !$this->isAllowedImageType($image['extension'])) {
88
                continue;
89
            }
90
91
            $path = date('Ym') . '/' . md5($v) . '.' . $image['extension'];
92
            Storage::disk(config('light.neditor.disk'))
93
                ->put($path, $image['data']);
94
            $urls[] = [
95
                'url' => Storage::disk(config('light.neditor.disk'))->url($path),
96
                'source' => $v,
97
                'state' => 'SUCCESS'
98
            ];
99
        }
100
101
        return [
102
           'list' => $urls
103
        ];
104
    }
105
106
    public function uploadVideo(Request $request)
107
    {
108
        if (config('light.image_upload.driver') !== 'local') {
109
            $class = config('light.image_upload.class');
110
            return call_user_func([new $class, 'uploadImage'], $request);
111
        }
112
113
        if (!$request->hasFile('file')) {
114
            return [
115
                'code' => 2,
116
                'msg' => '非法请求'
117
            ];
118
        }
119
        $file = $request->file('file');
120
        if (!$this->isValidVideo($file)) {
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type Illuminate\Http\UploadedFile[] and array and null; however, parameter $file of App\Http\Controllers\Adm...troller::isValidVideo() does only seem to accept Illuminate\Http\UploadedFile, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
        if (!$this->isValidVideo(/** @scrutinizer ignore-type */ $file)) {
Loading history...
121
            return [
122
                'code' => 3,
123
                'msg' => '文件不合要求'
124
            ];
125
        }
126
127
        $result = $file->store('video/' . date('Ym'), config('light.neditor.disk'));
128
        if (!$result) {
129
            return [
130
                'code' => 3,
131
                'msg' => '上传失败'
132
            ];
133
        }
134
135
        return [
136
            'code' => 200,
137
            'state' => 'SUCCESS', // 兼容ueditor
138
            'msg' => '',
139
            'url' => Storage::disk(config('light.neditor.disk'))->url($result),
140
        ];
141
    }
142
143
    public function uploadFile(Request $request)
144
    {
145
        if (config('light.image_upload.driver') !== 'local') {
146
            $class = config('light.image_upload.class');
147
            return call_user_func([new $class, 'uploadImage'], $request);
148
        }
149
150
        if (!$request->hasFile('file')) {
151
            return [
152
                'code' => 2,
153
                'msg' => '非法请求'
154
            ];
155
        }
156
        $file = $request->file('file');
157
        if (!$this->isValidFile($file)) {
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type Illuminate\Http\UploadedFile[] and array and null; however, parameter $file of App\Http\Controllers\Adm...ntroller::isValidFile() does only seem to accept Illuminate\Http\UploadedFile, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
        if (!$this->isValidFile(/** @scrutinizer ignore-type */ $file)) {
Loading history...
158
            return [
159
                'code' => 3,
160
                'msg' => '文件不合要求'
161
            ];
162
        }
163
164
        $result = $file->store('file/' . date('Ym'), config('light.neditor.disk'));
165
        if (!$result) {
166
            return [
167
                'code' => 3,
168
                'msg' => '上传失败'
169
            ];
170
        }
171
172
        return [
173
            'code' => 200,
174
            'state' => 'SUCCESS', // 兼容ueditor
175
            'msg' => '',
176
            'url' => Storage::disk(config('light.neditor.disk'))->url($result),
177
        ];
178
    }
179
180
    protected function isValidImage(UploadedFile $file)
181
    {
182
        $c = config('light.neditor.upload');
183
        $config = [
184
            'maxSize' => $c['imageMaxSize'],
185
            'AllowFiles' => $c['imageAllowFiles'],
186
        ];
187
188
        return $this->isValidUploadedFile($file, $config);
189
    }
190
191
    protected function isValidVideo(UploadedFile $file)
192
    {
193
        $c = config('light.neditor.upload');
194
        $config = [
195
            'maxSize' => $c['videoMaxSize'],
196
            'AllowFiles' => $c['videoAllowFiles'],
197
        ];
198
199
        return $this->isValidUploadedFile($file, $config);
200
    }
201
202
    protected function isValidFile(UploadedFile $file)
203
    {
204
        $c = config('light.neditor.upload');
205
        $config = [
206
            'maxSize' => $c['fileMaxSize'],
207
            'AllowFiles' => $c['fileAllowFiles'],
208
        ];
209
210
        return $this->isValidUploadedFile($file, $config);
211
    }
212
213
    protected function isValidUploadedFile(UploadedFile $file, array $config)
214
    {
215
        if (!$file->isValid() ||
216
            $file->getSize() > $config['maxSize'] ||
217
            !in_array(
218
                '.' . strtolower($file->getClientOriginalExtension()),
219
                $config['AllowFiles']
220
            ) ||
221
            !in_array(
222
                '.' . strtolower($file->guessExtension()),
0 ignored issues
show
Bug introduced by
It seems like $file->guessExtension() can also be of type null; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

222
                '.' . strtolower(/** @scrutinizer ignore-type */ $file->guessExtension()),
Loading history...
223
                $config['AllowFiles']
224
            )
225
        ) {
226
            return false;
227
        }
228
229
        return true;
230
    }
231
232
    protected function fetchImageFile($url)
233
    {
234
        try {
235
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
236
                return false;
237
            }
238
239
            if (extension_loaded('curl')) {
240
                $ch = curl_init();
241
                $options =  [
242
                    CURLOPT_URL => $url,
243
                    CURLOPT_RETURNTRANSFER => true,
244
                    CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2'
245
                ];
246
                curl_setopt_array($ch, $options);
247
                $data = curl_exec($ch);
248
                curl_close($ch);
249
                if (!$data) {
250
                    return false;
251
                }
252
253
                if (isWebp($data)) {
254
                    $image = Image::make(imagecreatefromwebp($url));
255
                    $extension = 'webp';
256
                } else {
257
                    $image = Image::make($data);
258
                }
259
            } else {
260
                $image = Image::make($url);
261
            }
262
        } catch (NotReadableException $e) {
263
            return false;
264
        }
265
266
        $mime = $image->mime();
267
        return [
268
            'extension' => $extension ?? ($mime ? strtolower(explode('/', $mime)[1]) : ''),
269
            'data' => $data
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.
Loading history...
270
        ];
271
    }
272
273
    protected function isAllowedImageType($extension)
274
    {
275
        $c = config('light.neditor.upload');
276
277
        return in_array('.' . $extension, $c['imageAllowFiles'], true);
278
    }
279
}
280