GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( b87887...138d7a )
by t
62:54 queued 27s
created

Upload::getErrorCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
/**
3
 * Class Upload
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 */
9
namespace icy2003\php\ihelpers;
10
11
use icy2003\php\I;
12
use icy2003\php\icomponents\file\LocalFile;
13
14
/**
15
 * 文件类上传类
16
 */
17
class Upload
18
{
19
    /**
20
     * 单例对象
21
     *
22
     * @var static
23
     */
24
    protected static $_instance;
25
26
    /**
27
     * 构造函数
28
     */
29
    private function __construct()
30
    {
31
    }
32
33
    /**
34
     * 克隆函数
35
     *
36
     * @return void
37
     */
38
    private function __clone()
39
    {
40
    }
41
42
    /**
43
     * 创建文件上传单例.
44
     *
45
     * @param array $config
46
     *                      formName 文件上传时的表单名,默认 'file'
47
     *                      sizeLimit 文件上传大小限制,默认 0,不限制
48
     *                      extLimit 文件类型限制,默认 [],不限制
49
     *
50
     * @return static
51
     */
52
    public static function create($config = [])
53
    {
54
        if (!static::$_instance instanceof static ) {
0 ignored issues
show
introduced by
static::_instance is always a sub-type of static.
Loading history...
55
            static::$_instance = new static();
56
            static::$_instance->__formName = I::get($config, 'formName', 'file');
57
            static::$_instance->__sizeLimit = static::$_instance->__getSizeLimit(I::get($config, 'sizeLimit', 0));
58
            static::$_instance->__extLimit = I::get($config, 'extLimit', []);
59
        }
60
61
        return static::$_instance;
62
    }
63
64
    /**
65
     * 下载一个文件
66
     *
67
     * @param string $fileName
68
     *
69
     * @return
70
     */
71
    public static function download($fileName)
72
    {
73
        try {
74
            $local = new LocalFile();
75
            if ($local->isFile($fileName)) {
76
                header('Content-type:application/octet-stream');
77
                header('Accept-Ranges:bytes');
78
                header('Accept-Length:' . $local->getFilesize($fileName));
79
                header('Content-Disposition: attachment; filename=' . Charset::toCn($local->getBasename($fileName)));
80
                foreach ($local->dataGenerator($fileName) as $data) {
81
                    echo $data;
82
                }
83
            }
84
        } catch (\Exception $e) {
85
            header('HTTP/1.1 404 Not Found');
86
            echo $e->getMessage();
87
        }
88
    }
89
90
    /**
91
     * 成功
92
     */
93
    const ERROR_SUCCESS = 0;
94
    /**
95
     * 超出 upload_max_filesize 选项限制
96
     */
97
    const ERROR_UPLOAD_MAX_FILESIZE = 1;
98
    /**
99
     * 超出表单中 MAX_FILE_SIZE 选项的值
100
     */
101
    const ERROR_MAX_FILE_SIZE = 2;
102
    /**
103
     * 文件只有部分被上传
104
     */
105
    const ERROR_PART_UPLOAD = 3;
106
    /**
107
     * 没有文件被上传
108
     */
109
    const ERROR_FILE_NOT_FOUND = 4;
110
    /**
111
     * 找不到临时文件夹
112
     */
113
    const ERROR_TEMP_DIR_NOT_FOUND = 6;
114
    /**
115
     * 文件写入失败
116
     */
117
    const ERROR_WRITE_FAILED = 7;
118
    /**
119
     * 文件扩展没有打开
120
     */
121
    const ERROR_EXT_CLOSE = 8;
122
    /**
123
     * 文件保存失败
124
     */
125
    const ERROR_SAVE_FAILED = -1;
126
    /**
127
     * 超出文件大小限制
128
     */
129
    const ERROR_SIZE_LIMIT = -2;
130
    /**
131
     * 不允许的文件类型
132
     */
133
    const ERROR_EXT_LIMIT = -3;
134
135
    /**
136
     * 没有文件字段
137
     */
138
    const ERROR_NO_FORM_FIELD = -4;
139
140
    /**
141
     * 错误信息列表
142
     *
143
     * @var array
144
     */
145
    private static $__errorMap = [
146
        self::ERROR_SUCCESS => '文件上传成功',
147
        self::ERROR_UPLOAD_MAX_FILESIZE => '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值',
148
        self::ERROR_MAX_FILE_SIZE => '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值',
149
        self::ERROR_PART_UPLOAD => '文件只有部分被上传',
150
        self::ERROR_FILE_NOT_FOUND => '没有文件被上传',
151
        self::ERROR_TEMP_DIR_NOT_FOUND => '找不到临时文件夹',
152
        self::ERROR_WRITE_FAILED => '文件写入失败',
153
        self::ERROR_EXT_CLOSE => ' php 文件上传扩展 file 没有打开',
154
        self::ERROR_SAVE_FAILED => '文件保存失败',
155
        self::ERROR_SIZE_LIMIT => '超出自定义的文件上传大小限制',
156
        self::ERROR_EXT_LIMIT => '不允许的文件类型',
157
        self::ERROR_NO_FORM_FIELD => '没有指定文件表单字段',
158
    ];
159
160
    /**
161
     * 属性列表
162
     *
163
     * @var array
164
     */
165
    private $__attributes = [];
166
    /**
167
     * 默认的上传表单字段名
168
     *
169
     * @var string
170
     */
171
    private $__formName = 'file';
172
    /**
173
     * 默认上传限制
174
     *
175
     * @var integer
176
     */
177
    private $__sizeLimit = 0;
178
    /**
179
     * 默认扩展限制
180
     *
181
     * @var array
182
     */
183
    private $__extLimit = [];
184
    /**
185
     * 错误代码
186
     *
187
     * @var integer
188
     */
189
    private $__errorCode = 0;
190
191
    /**
192
     * 文件上传,对上传的文件进行处理,需要用 save()、saveTo()、saveAs() 保存.
193
     *
194
     * @return static
195
     */
196
    public function upload()
197
    {
198
        if (false === isset($_FILES[$this->__formName])) {
199
            $this->__errorCode = self::ERROR_NO_FORM_FIELD;
200
            return $this;
201
        }
202
        if (self::ERROR_SUCCESS === $_FILES[$this->__formName]['error']) {
203
            if (is_uploaded_file($file = $_FILES[$this->__formName]['tmp_name'])) {
204
                $localFile = new LocalFile();
205
                $fileName = $_FILES[$this->__formName]['name'];
206
                $fileSize = $localFile->getFilesize($file);
207
                $fileExt = $localFile->getExtension($fileName);
208
                if ($fileSize > $this->__sizeLimit) {
209
                    $this->__errorCode = self::ERROR_SIZE_LIMIT;
210
211
                    return $this;
212
                }
213
                if (!empty($this->__extLimit) && !in_array($fileExt, $this->__extLimit)) {
214
                    $this->__errorCode = self::ERROR_EXT_LIMIT;
215
216
                    return $this;
217
                }
218
                $this->__attributes['md5'] = md5_file($file);
219
                $this->__attributes['sha1'] = sha1_file($file);
220
                $this->__attributes['ext'] = $fileExt;
221
                $this->__attributes['size'] = $fileSize;
222
                $this->__attributes['filectime'] = $localFile->splInfo($file)->getCTime();
223
                $this->__attributes['filemtime'] = $localFile->splInfo($file)->getMTime();
224
                $this->__attributes['fileatime'] = $localFile->splInfo($file)->getATime();
225
                $this->__attributes['originName'] = $fileName;
226
                $this->__attributes['fileName'] = date('YmdHis') . Strings::random(10) . '.' . $fileExt;
227
                $this->__errorCode = self::ERROR_SUCCESS;
228
229
                return $this;
230
            } else {
231
                $this->__errorCode = self::ERROR_SAVE_FAILED;
232
233
                return $this;
234
            }
235
        } else {
236
            // 其他错误时的处理
237
            $this->__errorCode = $_FILES[$this->__formName]['error'];
238
239
            return $this;
240
        }
241
    }
242
243
    /**
244
     * 保存文件至目录.
245
     *
246
     * @param string $dirPath 目录
247
     * @param string $fileName 文件名,如果不给则用系统随机的文件名
248
     *
249
     * @return boolean
250
     */
251
    public function saveTo($dirPath, $fileName = null)
252
    {
253
        $localFile = new LocalFile();
254
        $localFile->createDir($dirPath);
255
        null === $fileName && $fileName = $this->__attributes['fileName'];
256
        return move_uploaded_file($_FILES[$this->__formName]['tmp_name'], rtrim($dirPath, '/') . '/' . $fileName);
257
    }
258
259
    /**
260
     * 保存文件至路径或目录
261
     * - saveAs():$path 为文件时
262
     * - saveTo():$path 为目录时
263
     */
264
    public function save($path, $fileName = null)
265
    {
266
        $localFile = new LocalFile();
267
        if ($localFile->isFile($path)) {
268
            return $this->saveAs($path);
269
        } else {
270
            return $this->saveTo($path, $fileName);
271
        }
272
    }
273
274
    /**
275
     * 保存文件至指定路径.
276
     * - 注意:如果目标文件已存在但只是文件名相同,实际是不同的文件,则会修改 fileName 属性并且保存为新的文件
277
     *
278
     * @param string $filePath 文件路径
279
     *
280
     * @return boolean
281
     */
282
    public function saveAs($filePath)
283
    {
284
        $localFile = new LocalFile();
285
        $dirName = $localFile->getDirname($filePath);
286
        $localFile->createDir($dirName);
287
        $fileName = $localFile->getFilename($filePath);
288
        if ($localFile->isFile($filePath)) {
289
            if (md5_file($filePath) === $this->__attributes['md5'] && sha1_file($filePath) === $this->__attributes['sha1']) {
290
                return true;
291
            } else {
292
                $this->__attributes['fileName'] = $localFile->getBasename($fileName) . '_' . time() . '.' . $localFile->getExtension($fileName);
293
                return $this->saveAs($dirName . '/' . $this->__attributes['fileName']);
294
            }
295
        }
296
        return move_uploaded_file($_FILES[$this->__formName]['tmp_name'], $filePath);
297
    }
298
299
    /**
300
     * 文件上传的错误码
301
     *
302
     * @return string
303
     */
304
    public function getErrorCode()
305
    {
306
        return $this->__errorCode;
307
    }
308
309
    /**
310
     * 文件上传是否成功
311
     *
312
     * @return boolean
313
     */
314
    public function success()
315
    {
316
        return self::ERROR_SUCCESS === $this->__errorCode;
317
    }
318
319
    /**
320
     * 文件上传的错误信息.
321
     *
322
     * @return string
323
     */
324
    public function getErrorMessage()
325
    {
326
        return self::$__errorMap[$this->__errorCode];
327
    }
328
329
    /**
330
     * 返回上传后文件的属性.
331
     *
332
     * @return array
333
     */
334
    public function getAttributes()
335
    {
336
        return $this->__attributes;
337
    }
338
339
    /**
340
     * 结合系统限制,找出文件大小限制
341
     *
342
     * @param string $configLimit
343
     *
344
     * @return string
345
     */
346
    private function __getSizeLimit($configLimit)
347
    {
348
        $array = [
349
            Numbers::toBytes(I::phpini('upload_max_filesize', 0)),
0 ignored issues
show
Bug introduced by
It seems like icy2003\php\I::phpini('upload_max_filesize', 0) can also be of type array; however, parameter $size of icy2003\php\ihelpers\Numbers::toBytes() 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

349
            Numbers::toBytes(/** @scrutinizer ignore-type */ I::phpini('upload_max_filesize', 0)),
Loading history...
350
            Numbers::toBytes(I::phpini('post_max_size', 0)),
351
            Numbers::toBytes($configLimit),
352
        ];
353
        return min(array_filter($array));
354
    }
355
}
356