Passed
Push — main ( 5af531...3f4cd8 )
by Sammy
07:48 queued 01:06
created

File::getFilePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace HexMakina\LocalFS;
4
5
class File extends FileSystem
6
{
7
    private FilePath $path;
8
    private string $mode;
9
    private int $size_in_bytes = -1;
10
    private $pointer = null;
11
12
    private const MODE_REQUIRES_EXISTING_FILE = ['r', 'r+'];
13
    private const MODE_REQUIRES_UNEXISTING_FILE = ['x', 'x+'];
14
15
    // private static $modes_create_unexisting_file = ['w', 'w+', 'a', 'a+', 'c', 'c+'];
16
17
    public function __construct(string $path, string $mode = 'r')
18
    {
19
        if (!file_exists($path) && self::requiresExistingFile($mode)) {
20
            throw new \InvalidArgumentException('MODE_REQUIRES_EXISTING_FILE');
21
        }
22
23
        $this->path = new FilePath($path);
24
        $this->mode = $mode;
25
    }
26
27
    public function path(): string
28
    {
29
        return $this->path->__toString();
30
    }
31
32
    public function getFilePath(): FilePath
33
    {
34
        return $this->path;
35
    }
36
37
    public function open()
38
    {
39
        $this->pointer = fopen($this->path(), $this->mode);
40
        if ($this->pointer === false) {
41
            throw new \Exception('FILE_OPEN_FAILURE');
42
        }
43
        return $this->pointer;
44
    }
45
46
    public function pointer()
47
    {
48
        return $this->pointer ?? $this->open();
49
    }
50
51
    public function close()
52
    {
53
        if (!is_resource($this->pointer)) {
54
            return true;
55
        }
56
57
        if (fclose($this->pointer) === false) {
58
            throw new \Exception('FILE_CLOSE_FAILURE');
59
        }
60
61
        return true;
62
    }
63
64
    public function array()
65
    {
66
        return file($this->path);
67
    }
68
69
    public function setContent($content)
70
    {
71
        if (is_writable($this->path()) !== true && self::requiresExistingFile($this->mode)) {
72
            throw new \Exception('FILE_IS_NOT_WRITABLE');
73
        }
74
75
        $this->open();
76
        if (fwrite($this->pointer, $content) === false) {
77
            throw new \Exception('FILE_WRITE_FAILURE');
78
        }
79
        $this->close();
80
    }
81
82
   
83
    public function getMIMEType($fast=true): string
84
    {
85
        if($fast === true || extension_loaded('fileinfo') === false){
86
            return mime_content_type($this->path());
87
        }
88
89
        $res = finfo_open(FILEINFO_MIME_TYPE);
90
91
        if ($res === false) {
92
            throw new \Exception('UNABLE_TO_OPEN_FILEINFO');
93
        }
94
95
        $mimeType = finfo_file($res, $this->path());
96
97
        finfo_close($res);
98
99
        if ($mimeType === false) {
100
            throw new \Exception('UNABLE_TO_DETECT_MIME_TYPE');
101
        }
102
103
        return $mimeType;
104
    }
105
106
    public function size(): int
107
    {
108
        if ($this->size_in_bytes === -1 && ($res = filesize($this->path())) !== false) {
109
            $this->size_in_bytes = $res;
110
        }
111
112
        return $this->size_in_bytes;
113
    }
114
115
    private static function requiresExistingFile($mode)
116
    {
117
        return in_array($mode, self::MODE_REQUIRES_EXISTING_FILE);
118
    }
119
120
}
121