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
Branch dev (73721b)
by t
02:17
created

LocalFile::getType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
c 1
b 1
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * Class LocalFile
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2019, icy2003
8
 */
9
namespace icy2003\php\icomponents\file;
10
11
use Exception;
12
use icy2003\php\C;
13
use icy2003\php\I;
14
use icy2003\php\icomponents\file\FileInterface;
15
use icy2003\php\ihelpers\Arrays;
16
use icy2003\php\ihelpers\Console;
17
use icy2003\php\ihelpers\Header;
18
use icy2003\php\ihelpers\Request;
19
use icy2003\php\ihelpers\Strings;
20
21
/**
22
 * 本地文件
23
 *
24
 * - 支持本地文件操作
25
 * - 支持网络文件部分属性:文件是否存在、文件大小
26
 */
27
class LocalFile extends Base implements FileInterface
28
{
29
30
    /**
31
     * 配置
32
     *
33
     * @var array
34
     */
35
    protected $_c = [
36
        'loader' => 'curl',
37
        'locale' => 'zh_CN.UTF-8',
38
        'buffer' => 4096,
39
        'mode' => 'rb',
40
        'rtrim' => true,
41
    ];
42
43
    /**
44
     * 文件属性
45
     *
46
     * - 文件名为键,属性为值
47
     *
48
     * @var array
49
     */
50
    protected $_attributes = [];
51
52
    /**
53
     * 初始化
54
     *
55
     * @param array $options 配置
56
     *      - locale:地区,默认 zh_CN.UTF-8
57
     *      - buffer:以字节方式读写时每段的字节长度,默认为 4096,即 4kb
58
     *      - mode:指定了所要求到该流的访问类型,默认 rb @link https://www.php.net/manual/zh/function.fopen.php
59
     *      - rtrim:在遍历行时是否去除行尾空白,默认 true,即去除
60
     *      - loader:读取远程资源时用的方法,默认为 curl(当其他方法无法读取时也会设置为 curl),支持值:curl、fopen、fsockopen
61
     *          - curl:使用 curl 获取远程文件信息
62
     *          - fopen:需要手动开启 allow_url_fopen 才能使用,不建议开启
63
     *          - fsockopen:使用 fsockopen 发送头获取信息
64
     * @return void
65
     */
66 36
    public function __construct($options = [])
67
    {
68 36
        $this->_c = Arrays::merge($this->_c, $options);
69 36
        setlocale(LC_ALL, (string) I::get($this->_c, 'locale', 'zh_CN.UTF-8'));
70 36
        clearstatcache();
71 36
    }
72
73
    /**
74
     * 获取 Hash 值
75
     *
76
     * @param string $fileName
77
     *
78
     * @return string
79
     */
80 13
    private function __hash($fileName)
81
    {
82 13
        return md5($fileName);
83
    }
84
85
    /**
86
     * 以别名返回路径
87
     *
88
     * @param string $file
89
     *
90
     * @return string
91
     */
92 34
    private function __file($file)
93
    {
94 34
        return (string) I::getAlias($file);
95
    }
96
97
    /**
98
     * 加载一个文件,本地(支持别名)或网络文件
99
     *
100
     * @param string $fileName
101
     *
102
     * @return static
103
     */
104 8
    protected function _load($fileName)
105
    {
106 8
        $fileName = $this->getRealpath($fileName);
107 8
        $hashName = $this->__hash($fileName);
108 8
        $this->_attributes[$hashName] = I::get($this->_attributes, $hashName, [
109 8
            'file' => $fileName,
110
            'isCached' => false,
111
            'isLocal' => true,
112
            // 以下属性需要重新设置
113
            'isExists' => false,
114 8
            'fileSize' => 0,
115
            'spl' => null,
116
            'splInfo' => null,
117
        ]);
118 8
        null === $this->_attributes[$hashName]['splInfo'] && $this->_attributes[$hashName]['splInfo'] = new \SplFileInfo($fileName);
119
        try {
120 8
            $splInfo = $this->_attributes[$hashName]['splInfo'];
121 8
            if (true !== $splInfo->isDir()) {
122 8
                null === $this->_attributes[$hashName]['spl'] && $this->_attributes[$hashName]['spl'] = new \SplFileObject($fileName, $this->_c['mode']);
123
            }
124 1
        } catch (Exception $e) {
125
            // 报错了也得继续跑,如果跑完一次 spl 和 splInfo 属性还是 null,在调用它们的时候自然会报错
126 1
            $this->_c['error'] = $e->getMessage();
127
            // 尝试用 curl 获取
128 1
            $this->_c['loader'] = 'curl';
129
        }
130
        // 如果已经被缓存了,直接返回
131 8
        if (true === $this->_attributes[$hashName]['isCached']) {
132 2
            return $this;
133
        }
134
        // 加上缓存标记
135 8
        $this->_attributes[$hashName]['isCached'] = true;
136 8
        if (preg_match('/^https?:\/\//', $fileName)) {
137 1
            $this->_attributes[$hashName]['isLocal'] = false;
138
            // 加载网络文件
139 1
            if ('curl' === $this->_c['loader'] && extension_loaded('curl')) {
140 1
                $curl = curl_init($fileName);
141 1
                if (is_resource($curl)) {
142 1
                    curl_setopt($curl, CURLOPT_NOBODY, true);
143 1
                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
144 1
                    curl_setopt($curl, CURLOPT_HEADER, true);
145
                    // 公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)
146
                    // - 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)
147
                    // - 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配
148
                    // - 0 为不检查名称。 在生产环境中,这个值应该是 2(默认值)
149 1
                    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
150
                    // 禁止 cURL 验证对等证书(peer's certificate)。要验证的交换证书可以在 CURLOPT_CAINFO 选项中设置
151 1
                    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
152 1
                    $result = curl_exec($curl);
153 1
                    if ($result && $info = curl_getinfo($curl)) {
154 1
                        if (200 == $info['http_code']) {
155 1
                            $this->_attributes[$hashName]['isExists'] = true;
156 1
                            $this->_attributes[$hashName]['fileSize'] = (int) $info['download_content_length'];
157
                        }
158
                    }
159 1
                    curl_close($curl);
160
                }
161 1
                return $this;
162
            }
163 1
            if ('fsockopen' === $this->_c['loader']) {
164 1
                $url = parse_url($fileName);
165 1
                $host = $url['host'];
166 1
                $path = (string) I::get($url, 'path', '/');
167 1
                $port = (int) I::get($url, 'port', 80);
168 1
                $fp = fsockopen($host, $port);
169 1
                if (is_resource($fp)) {
170 1
                    fputs($fp, "GET {$path} HTTP/1.1\r\n");
171 1
                    fputs($fp, "Host: {$host}:{$port}\r\n");
172 1
                    fputs($fp, "Connection: Close\r\n\r\n");
173 1
                    while (!feof($fp)) {
174 1
                        $line = fgets($fp);
175 1
                        preg_match('/HTTP.*(\s\d{3}\s)/', $line, $arr) && $this->_attributes[$hashName]['isExists'] = true;
176 1
                        preg_match('/Content-Length:(.*)/si', $line, $arr) && $this->_attributes[$hashName]['fileSize'] = (int) trim($arr[1]);
177
                    }
178 1
                    fclose($fp);
179
                }
180 1
                return $this;
181
            }
182 1
            if ('fopen' === $this->_c['loader'] && (bool) ini_get('allow_url_fopen')) {
183 1
                $headArray = (array) get_headers($fileName, 1);
184 1
                if (preg_match('/200/', $headArray[0])) {
185 1
                    $this->_attributes[$hashName]['isExists'] = true;
186 1
                    $this->_attributes[$hashName]['fileSize'] = (int) $headArray['Content-Length'];
187
                }
188 1
                return $this;
189
            }
190
        } else {
191 7
            $this->_attributes[$hashName]['isLocal'] = true;
192 7
            $this->_attributes[$hashName]['isExists'] = file_exists($fileName);
193 7
            if ($this->_attributes[$hashName]['isExists']) {
194 6
                $this->_attributes[$hashName]['fileSize'] = filesize($fileName);
195
            }
196 7
            $this->chmod($fileName, 0777, FileConstants::RECURSIVE_DISABLED);
197
        }
198 7
        return $this;
199
    }
200
201
    /**
202
     * 获取文件的属性
203
     *
204
     * @param string $fileName
205
     * @param string $name
206
     *
207
     * @return mixed
208
     */
209 8
    public function attribute($fileName, $name)
210
    {
211 8
        $this->_load($fileName);
212 8
        return I::get($this->_attributes, $this->__hash($this->getRealpath($fileName)) . '.' . $name);
213
    }
214
215
    /**
216
     * 获取文件对象
217
     *
218
     * @param string $fileName
219
     * @param string $mode 读写的模式,默认 rb
220
     *
221
     * @return \SplFileObject|null
222
     */
223 5
    public function spl($fileName, $mode = 'rb')
224
    {
225 5
        $this->_c['mode'] = $mode;
226 5
        $spl = $this->attribute($fileName, 'spl');
227 5
        C::assertTrue($spl instanceof \SplFileObject, '文件打开失败:' . $fileName);
228 4
        return $spl;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $spl also could return the type false|string which is incompatible with the documented return type SplFileObject|null.
Loading history...
229
    }
230
231
    /**
232
     * 获取文件信息对象
233
     *
234
     * @param string $fileName
235
     *
236
     * @return \SplFileInfo|null
237
     */
238 1
    public function splInfo($fileName)
239
    {
240 1
        $splInfo = $this->attribute($fileName, 'splInfo');
241 1
        C::assertTrue($splInfo instanceof \SplFileInfo, '文件打开失败:' . $fileName);
242 1
        return $splInfo;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $splInfo also could return the type false|string which is incompatible with the documented return type SplFileInfo|null.
Loading history...
243
    }
244
245
    /**
246
     * 遍历行的生成器
247
     *
248
     * - 自动关闭后再次调用需要重新读取文件,不建议自动关闭
249
     *
250
     * @param string $fileName
251
     * @param boolean $autoClose 是否自动关闭文件,默认 false
252
     *
253
     * @return \Generator
254
     */
255 2
    public function linesGenerator($fileName, $autoClose = false)
256
    {
257
        try {
258 2
            $spl = $this->spl($fileName, 'r');
259 2
            while (false === $spl->eof() && ($line = $spl->fgets())) {
260 2
                true === $this->_c['rtrim'] && $line = rtrim($line);
261 2
                yield $line;
262
            }
263 2
        } finally {
264 2
            true === $autoClose && $this->close($fileName);
265
        }
266 2
    }
267
268
    /**
269
     * 返回文本的某行
270
     *
271
     * - 每取一行,文件指针会回到初始位置,如果需要大量的行,请直接使用 linesGenerator
272
     * - 自动关闭后再次调用需要重新读取文件,不建议自动关闭
273
     *
274
     * @param string $fileName
275
     * @param integer $lineNumber 行号
276
     * @param boolean $autoClose 是否自动关闭文件,默认 false
277
     *
278
     * @return string|null
279
     */
280 1
    public function line($fileName, $lineNumber = 0, $autoClose = false)
281
    {
282 1
        $spl = $this->spl($fileName, 'r');
283 1
        $lineNumber = (int) $lineNumber;
284 1
        foreach ($this->linesGenerator($fileName, $autoClose) as $k => $line) {
285 1
            if ($k === $lineNumber) {
286 1
                $spl->rewind();
287 1
                return $line;
288
            }
289
        }
290 1
        return null;
291
    }
292
293
    /**
294
     * 遍历字节的生成器
295
     *
296
     * - 自动关闭后再次调用需要重新读取文件,不建议自动关闭
297
     *
298
     * @param string $fileName
299
     * @param boolean $autoClose 是否自动关闭文件,默认 false
300
     * @param integer|null $buffer 每次读取的字节数,默认 null,值等于初始化时的 buffer 选项
301
     *
302
     * @return \Generator
303
     */
304 1
    public function dataGenerator($fileName, $autoClose = false, $buffer = null)
305
    {
306 1
        $bufferSize = 0;
307 1
        null === $buffer && $buffer = $this->_c['buffer'];
308
        try {
309 1
            $spl = $this->spl($fileName, 'rb');
310 1
            $size = $this->getFilesize($fileName);
311 1
            while (!$spl->eof() && $size > $bufferSize) {
312 1
                $bufferSize += $buffer;
313 1
                yield $spl->fread($bufferSize);
314
            }
315 1
        } finally {
316 1
            true === $autoClose && $this->close($fileName);
317
        }
318 1
    }
319
320
    /**
321
     * @ignore
322
     */
323 1
    public function getATime($fileName)
324
    {
325 1
        return fileatime($this->__file($fileName));
326
    }
327
328
    /**
329
     * @ignore
330
     */
331 2
    public function getBasename($file, $suffix = null)
332
    {
333 2
        return parent::getBasename($this->__file($file), $suffix);
334
    }
335
336
    /**
337
     * @ignore
338
     */
339 1
    public function getCTime($fileName)
340
    {
341 1
        return filectime($this->__file($fileName));
342
    }
343
344
    /**
345
     * @ignore
346
     */
347 1
    public function getExtension($fileName)
348
    {
349 1
        return pathinfo($this->__file($fileName), PATHINFO_EXTENSION);
350
    }
351
352
    /**
353
     * @ignore
354
     */
355 1
    public function getFilename($fileName)
356
    {
357 1
        return pathinfo($this->__file($fileName), PATHINFO_FILENAME);
358
    }
359
360
    /**
361
     * @ignore
362
     */
363 1
    public function getMtime($fileName)
364
    {
365 1
        return filemtime($this->__file($fileName));
366
    }
367
368
    /**
369
     * @ignore
370
     */
371 5
    public function getDirname($path)
372
    {
373 5
        return parent::getDirname($this->__file($path));
374
    }
375
376
    /**
377
     * @ignore
378
     */
379 1
    public function getPerms($path)
380
    {
381 1
        return fileperms($this->__file($path));
382
    }
383
384
    /**
385
     * @ignore
386
     */
387 3
    public function getFilesize($fileName)
388
    {
389 3
        return (int) $this->attribute($fileName, 'fileSize');
390
    }
391
392
    /**
393
     * @ignore
394
     */
395 1
    public function getType($path)
396
    {
397 1
        return filetype($this->__file($path));
398
    }
399
400
    /**
401
     * @ignore
402
     */
403 13
    public function isDir($dir)
404
    {
405 13
        return is_dir($this->__file($dir));
406
    }
407
408
    /**
409
     * @ignore
410
     */
411 1
    public function isDot($dir)
412
    {
413 1
        return in_array($this->getBasename($dir), ['.', '..']);
414
    }
415
416
    /**
417
     * @ignore
418
     */
419 16
    public function isFile($file)
420
    {
421 16
        return is_file($this->__file($file));
422
    }
423
424
    /**
425
     * @ignore
426
     */
427 1
    public function isLink($link)
428
    {
429 1
        return is_link($this->__file($link));
430
    }
431
432
    /**
433
     * @ignore
434
     */
435 1
    public function isReadable($path)
436
    {
437 1
        return is_readable($this->__file($path));
438
    }
439
440
    /**
441
     * @ignore
442
     */
443 1
    public function isWritable($path)
444
    {
445 1
        return is_writable($this->__file($path));
446
    }
447
448
    /**
449
     * @ignore
450
     */
451 1
    public function getCommandResult($command)
452
    {
453 1
        return Console::exec($command);
454
    }
455
456
    /**
457
     * @ignore
458
     */
459 14
    public function getRealpath($path)
460
    {
461 14
        $path = $this->__file($path);
462 14
        $realPath = realpath($path);
463 14
        false === $realPath && $realPath = parent::getRealpath($path);
464 14
        return Strings::replace($realPath, ["\\" => '/']);
465
    }
466
467
    /**
468
     * @ignore
469
     */
470 3
    public function getLists($dir = null, $flags = FileConstants::COMPLETE_PATH | FileConstants::RECURSIVE_DISABLED)
471
    {
472 3
        null === $dir && $dir = $this->getRealpath('./');
473 3
        $dir = rtrim($this->__file($dir), '/') . '/';
474 3
        $iterator = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS);
475 3
        if (I::hasFlag($flags, FileConstants::RECURSIVE)) {
476 3
            $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
477
        }
478 3
        $files = [];
479
        /**
480
         * @var \RecursiveDirectoryIterator $file
481
         */
482 3
        foreach ($iterator as $file) {
483 3
            if (I::hasFlag($flags, FileConstants::COMPLETE_PATH)) {
484 3
                $files[] = $file->getPathname();
485
            } else {
486 2
                $files[] = $file->getFilename();
487
            }
488
        }
489 3
        return $files;
490
    }
491
492
    /**
493
     * @ignore
494
     */
495 2
    public function getFileContent($file)
496
    {
497 2
        return file_get_contents($this->__file($file));
498
    }
499
500
    /**
501
     * @ignore
502
     */
503 1
    public function putFileContent($file, $string, $mode = 0777)
504
    {
505 1
        $this->createDir($this->getDirname($file), $mode);
506 1
        $isCreated = false !== file_put_contents($this->__file($file), $string);
507 1
        $this->chmod($file, $mode, FileConstants::RECURSIVE_DISABLED);
508 1
        return $isCreated;
509
    }
510
511
    /**
512
     * @ignore
513
     */
514 5
    public function deleteFile($file)
515
    {
516 5
        if ($this->isFile($file)) {
517 5
            $this->close($file);
518 5
            return unlink($this->__file($file));
519
        }
520 1
        return true;
521
    }
522
523
    /**
524
     * @ignore
525
     */
526 1
    public function uploadFile($fileMap, $overwrite = true)
527
    {
528 1
        return false;
529
    }
530
531
    /**
532
     * - 从远程下载文件到本地
533
     * @param callback|null $callback 执行中的回调([当前下载的字节], [总字节])
534
     * @param callback|null $finishCallback 执行完成后的回调([本地文件 \SplFileObject])
535
     *
536
     * @ignore
537
     */
538 1
    public function downloadFile($fileMap, $overwrite = true, $callback = null, $finishCallback = null)
539
    {
540 1
        set_time_limit(0);
541 1
        list($fromFile, $toFile) = $this->fileMap($fileMap);
542 1
        $toSpl = $this->spl($toFile, 'wb');
543
        if ($this->isFile($toFile) && false === $overwrite) {
544
            $this->close($toFile);
545
            I::call($finishCallback, [$toSpl]);
546
            return true;
547
        }
548
        $fromSpl = $this->spl($fromFile, 'rb');
549
        $size = 0;
550
        $total = $this->getFilesize($fromFile);
551
        while (false === $fromSpl->eof()) {
552
            $out = $fromSpl->fread($this->_c['buffer']);
553
            $toSpl->fwrite($out);
554
            $size += Strings::byteLength($out);
555
            I::call($callback, [$size, $total]);
556
        }
557
        $this->close([$fromFile, $toFile]);
558
        I::call($finishCallback, [$toSpl]);
559
    }
560
561
    /**
562
     * download() 配置名:ip
563
     */
564
    const C_DOWNLOAD_IP = 'ip';
565
    /**
566
     * download() 配置名:speed
567
     */
568
    const C_DOWNLOAD_SPEED = 'speed';
569
    /**
570
     * download() 配置名:xSendFile
571
     */
572
    const C_DOWNLOAD_X_SEND_FILE = 'xSendFile';
573
    /**
574
     * download() 配置名:xSendFileRoot
575
     */
576
    const C_DOWNLOAD_X_SEND_FILE_ROOT = 'xSendFileRoot';
577
578
    /**
579
     * 服务端给客户端提供下载请求
580
     *
581
     * @param string|array $fileName self::fileMap()
582
     * @param null|array $config 配置项
583
     *      - ip:限特定 IP 访问,数组或逗号字符串,默认为 *,即对所有 IP 不限制
584
     *      - speed:限速,默认不限速(读取速度为1024 * [buffer]),单位 kb/s
585
     *      - xSendFile:是否使用 X-Sendfile 进行下载,默认 false,即不使用。X-Sendfile 缓解了 PHP 的压力,但同时 PHP 将失去对资源的控制权,因为 PHP 并不知道资源发完了没
586
     *      - xSendFileRoot:文件根路径,默认为 /protected/。此时 Nginx 可作如下配置,更多 @link https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
587
     *      ```nginx.conf
588
     *      location /protected/ {
589
     *          internal; # 表示这个路径只能在 Nginx 内部访问,不能用浏览器直接访问防止未授权的下载
590
     *          alias   /usr/share/nginx/html/protected/; # 别名
591
     *          # root    /usr/share/nginx/html; # 根目录
592
     *      }
593
     *      ```
594
     * @param callback $callback 下载完成后的回调,参数列表:文件属性数组
595
     *
596
     * @return void
597
     * @throws Exception
598
     */
599
    public function download($fileName, $config = null, $callback = null)
600
    {
601
        Header::xPoweredBy();
602
        set_time_limit(0);
603
        list($originName, $downloadName) = $this->fileMap($fileName);
604
        $originName = $this->__file($originName);
605
        try {
606
            $ip = (string) I::get($config, self::C_DOWNLOAD_IP, '*');
607
            if ('*' !== $ip) {
608
                C::assertTrue(Arrays::in((new Request())->getUserIP(), Strings::toArray($ip)), 'http/1.1 403.6 此 IP 禁止访问');
609
            }
610
            if ($this->isFile($originName)) {
611
                $fileSize = $this->getFilesize($originName);
612
                header('Content-type:application/octet-stream');
613
                header('Accept-Ranges:bytes');
614
                header('Content-Length:' . $fileSize);
615
                header('Content-Disposition: attachment; filename=' . $downloadName);
616
                $speed = (int) I::get($config, self::C_DOWNLOAD_SPEED, 0);
617
                $xSendFile = I::get($config, self::C_DOWNLOAD_X_SEND_FILE, false);
618
                $xSendFileRoot = (string) I::get($config, self::C_DOWNLOAD_X_SEND_FILE_ROOT, '/protected/');
619
                if (true === $xSendFile) {
620
                    $path = rtrim($xSendFileRoot, '/') . '/' . $this->getBasename($originName);
621
                    header('X-Accel-Redirect: ' . $path); // Nginx、Cherokee 实现了该头
622
                    header('X-Sendfile: ' . $path); // Apache、Lighttpd v1.5、Cherokee 实现了该头
623
                    header('X-LIGHTTPD-send-file: ' . $path); // Lighttpd v1.4 实现了该头
624
                    if ($speed) {
625
                        header('X-Accel-Limit-Rate: ' . $speed); // 单位 kb/s
626
                    }
627
                } else {
628
                    flush();
629
                    foreach ($this->dataGenerator($originName, true, ($speed ? $speed : $this->_c['buffer'] * 1024)) as $data) {
630
                        echo $data;
631
                        flush();
632
                        $speed > 0 && sleep(1);
633
                    }
634
                }
635
            }
636
        } catch (Exception $e) {
637
            header($e->getMessage());
638
        } finally {
639
            I::call($callback, [$this->_attributes]);
640
            // 必须要终止掉,防止发送其他数据导致错误
641
            die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
642
        }
643
    }
644
645
    /**
646
     * @ignore
647
     */
648
    public function chown($file, $user, $flags = FileConstants::RECURSIVE_DISABLED)
649
    {
650
        $file = $this->__file($file);
651
        if ($this->isDir($file) && I::hasFlag($flags, FileConstants::RECURSIVE)) {
652
            $files = $this->getLists($file, FileConstants::COMPLETE_PATH | FileConstants::RECURSIVE);
653
            foreach ($files as $subFile) {
654
                /** @scrutinizer ignore-unhandled */@chown($subFile, $user);
655
            }
656
        } elseif ($this->isFile($file)) {
657
            return /** @scrutinizer ignore-unhandled */@chown($file, $user);
658
        } else {
659
            return false;
660
        }
661
    }
662
663
    /**
664
     * @ignore
665
     */
666
    public function chgrp($file, $group, $flags = FileConstants::RECURSIVE_DISABLED)
667
    {
668
        $file = $this->__file($file);
669
        if ($this->isDir($file) && I::hasFlag($flags, FileConstants::RECURSIVE)) {
670
            $files = $this->getLists($file, FileConstants::COMPLETE_PATH | FileConstants::RECURSIVE);
671
            foreach ($files as $subFile) {
672
                /** @scrutinizer ignore-unhandled */@chgrp($subFile, $group);
673
            }
674
        } elseif ($this->isFile($file)) {
675
            return /** @scrutinizer ignore-unhandled */@chgrp($file, $group);
676
        } else {
677
            return false;
678
        }
679
    }
680
681
    /**
682
     * @ignore
683
     */
684 9
    public function chmod($file, $mode = 0777, $flags = FileConstants::RECURSIVE_DISABLED)
685
    {
686 9
        $file = $this->__file($file);
687 9
        if ($this->isDir($file) && I::hasFlag($flags, FileConstants::RECURSIVE)) {
688 1
            $files = $this->getLists($file, FileConstants::COMPLETE_PATH | FileConstants::RECURSIVE);
689 1
            foreach ($files as $subFile) {
690 1
                /** @scrutinizer ignore-unhandled */@chmod($subFile, $mode);
691
            }
692 8
        } elseif ($this->isFile($file)) {
693 7
            return /** @scrutinizer ignore-unhandled */@chmod($file, $mode);
694
        } else {
695 1
            return false;
696
        }
697 1
    }
698
699
    /**
700
     * @ignore
701
     */
702
    public function symlink($from, $to)
703
    {
704
        $from = $this->__file($from);
705
        $to = $this->__file($to);
706
        return @symlink($from, $to);
707
    }
708
709
    /**
710
     * @ignore
711
     */
712 35
    public function close($fileName = null)
713
    {
714 35
        if (is_string($fileName)) {
715 8
            $fileName = [$this->__hash($this->getRealpath($fileName))];
716 35
        } elseif (is_array($fileName)) {
717
            foreach ($fileName as $k => $name) {
718
                $fileName[$k] = $this->__hash($this->getRealpath($name));
719
            }
720
        }
721 35
        foreach ($this->_attributes as $hashName => /** @scrutinizer ignore-unused */$attribute) {
722 7
            if (null === $fileName || is_array($fileName) && in_array($hashName, $fileName)) {
723 7
                unset($this->_attributes[$hashName]);
724
            }
725
        }
726 35
        return true;
727
    }
728
729
    /**
730
     * @ignore
731
     */
732 3
    protected function _copy($fromFile, $toFile)
733
    {
734 3
        $fromFile = $this->__file($fromFile);
735 3
        $toFile = $this->__file($toFile);
736 3
        return copy($fromFile, $toFile);
737
    }
738
739
    /**
740
     * @ignore
741
     */
742 1
    protected function _move($fromFile, $toFile)
743
    {
744 1
        $fromFile = $this->__file($fromFile);
745 1
        $toFile = $this->__file($toFile);
746 1
        return rename($fromFile, $toFile);
747
    }
748
749
    /**
750
     * @ignore
751
     */
752 1
    protected function _mkdir($dir, $mode = 0777)
753
    {
754 1
        $dir = $this->__file($dir);
755 1
        return mkdir($dir, $mode);
756
    }
757
758
    /**
759
     * @ignore
760
     */
761 1
    protected function _rmdir($dir)
762
    {
763 1
        $dir = $this->__file($dir);
764 1
        return rmdir($dir);
765
    }
766
767
}
768