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.

LocalFile::__file()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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