NEditorController   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 264
Duplicated Lines 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
eloc 147
c 3
b 2
f 0
dl 0
loc 264
rs 9.28
wmc 39

11 Methods

Rating   Name   Duplication   Size   Complexity  
A catchImage() 0 27 6
A uploadImage() 0 34 5
A uploadVideo() 0 34 5
A serve() 0 10 2
A isValidVideo() 0 9 1
A isValidImage() 0 9 1
A uploadFile() 0 34 5
A isValidFile() 0 9 1
A isValidUploadedFile() 0 17 5
A isAllowedImageType() 0 5 1
B fetchImageFile() 0 42 7
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']);
0 ignored issues
show
Bug introduced by
It seems like $image['data'] can also be of type true; however, parameter $contents of Illuminate\Filesystem\FilesystemAdapter::put() does only seem to accept resource|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

93
                ->put($path, /** @scrutinizer ignore-type */ $image['data']);
Loading history...
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
            $ch = curl_init();
240
            $options =  [
241
                CURLOPT_URL => $url,
242
                CURLOPT_RETURNTRANSFER => true,
243
                CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2'
244
            ];
245
            curl_setopt_array($ch, $options);
246
            $data = curl_exec($ch);
247
            curl_close($ch);
248
            if (!$data) {
249
                return false;
250
            }
251
252
            if (isWebp($data)) {
253
                $image = Image::make(imagecreatefromwebp($url));
254
                $extension = 'webp';
255
            } else {
256
                $resource = @imagecreatefromstring($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type true; however, parameter $image of imagecreatefromstring() 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

256
                $resource = @imagecreatefromstring(/** @scrutinizer ignore-type */ $data);
Loading history...
257
258
                if ($resource === false) {
259
                    throw new NotReadableException(
260
                        "Unable to init from given binary data."
261
                    );
262
                }
263
                $image = Image::make($resource);
264
                $image->mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type true; however, parameter $string of finfo_buffer() 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

264
                $image->mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), /** @scrutinizer ignore-type */ $data);
Loading history...
265
            }
266
        } catch (NotReadableException $e) {
267
            return false;
268
        }
269
270
        $mime = $image->mime();
271
        return [
272
            'extension' => $extension ?? ($mime ? strtolower(explode('/', $mime)[1]) : ''),
273
            'data' => $data
274
        ];
275
    }
276
277
    protected function isAllowedImageType($extension)
278
    {
279
        $c = config('light.neditor.upload');
280
281
        return in_array('.' . $extension, $c['imageAllowFiles'], true);
282
    }
283
}
284