1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Gaufrette\Adapter\Local; |
4
|
|
|
|
5
|
|
|
use Gaufrette\Stream; |
6
|
|
|
use Gaufrette\StreamMode; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Local stream. |
10
|
|
|
* |
11
|
|
|
* @author Antoine Hérault <[email protected]> |
12
|
|
|
*/ |
13
|
|
View Code Duplication |
class LocalStream implements Stream |
|
|
|
|
14
|
|
|
{ |
15
|
|
|
private $path; |
16
|
|
|
private $mode; |
17
|
|
|
private $fileHandle; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @param string $path |
21
|
|
|
*/ |
22
|
|
|
public function __construct($path) |
23
|
|
|
{ |
24
|
|
|
$this->path = $path; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* {@inheritdoc} |
29
|
|
|
*/ |
30
|
|
|
public function open(StreamMode $mode) |
31
|
|
|
{ |
32
|
|
|
$baseDirPath = \Gaufrette\Util\Path::dirname($this->path); |
33
|
|
|
if ($mode->allowsWrite() && !is_dir($baseDirPath)) { |
34
|
|
|
@mkdir($baseDirPath, 0755, true); |
|
|
|
|
35
|
|
|
} |
36
|
|
|
try { |
37
|
|
|
$fileHandle = @fopen($this->path, $mode->getMode()); |
38
|
|
|
} catch (\Exception $e) { |
39
|
|
|
$fileHandle = false; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
if (false === $fileHandle) { |
43
|
|
|
throw new \RuntimeException(sprintf('File "%s" cannot be opened', $this->path)); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
$this->mode = $mode; |
47
|
|
|
$this->fileHandle = $fileHandle; |
48
|
|
|
|
49
|
|
|
return true; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* {@inheritdoc} |
54
|
|
|
*/ |
55
|
|
|
public function read($count) |
56
|
|
|
{ |
57
|
|
|
if (!$this->fileHandle) { |
58
|
|
|
return false; |
|
|
|
|
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
if (false === $this->mode->allowsRead()) { |
62
|
|
|
throw new \LogicException('The stream does not allow read.'); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return fread($this->fileHandle, $count); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* {@inheritdoc} |
70
|
|
|
*/ |
71
|
|
|
public function write($data) |
72
|
|
|
{ |
73
|
|
|
if (!$this->fileHandle) { |
74
|
|
|
return false; |
|
|
|
|
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
if (false === $this->mode->allowsWrite()) { |
78
|
|
|
throw new \LogicException('The stream does not allow write.'); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
return fwrite($this->fileHandle, $data); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* {@inheritdoc} |
86
|
|
|
*/ |
87
|
|
|
public function close() |
88
|
|
|
{ |
89
|
|
|
if (!$this->fileHandle) { |
90
|
|
|
return false; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
$closed = fclose($this->fileHandle); |
94
|
|
|
|
95
|
|
|
if ($closed) { |
96
|
|
|
$this->mode = null; |
97
|
|
|
$this->fileHandle = null; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
return $closed; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* {@inheritdoc} |
105
|
|
|
*/ |
106
|
|
|
public function flush() |
107
|
|
|
{ |
108
|
|
|
if ($this->fileHandle) { |
109
|
|
|
return fflush($this->fileHandle); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return false; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* {@inheritdoc} |
117
|
|
|
*/ |
118
|
|
|
public function seek($offset, $whence = SEEK_SET) |
119
|
|
|
{ |
120
|
|
|
if ($this->fileHandle) { |
121
|
|
|
return 0 === fseek($this->fileHandle, $offset, $whence); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
return false; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* {@inheritdoc} |
129
|
|
|
*/ |
130
|
|
|
public function tell() |
131
|
|
|
{ |
132
|
|
|
if ($this->fileHandle) { |
133
|
|
|
return ftell($this->fileHandle); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return false; |
|
|
|
|
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* {@inheritdoc} |
141
|
|
|
*/ |
142
|
|
|
public function eof() |
143
|
|
|
{ |
144
|
|
|
if ($this->fileHandle) { |
145
|
|
|
return feof($this->fileHandle); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return true; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* {@inheritdoc} |
153
|
|
|
*/ |
154
|
|
|
public function stat() |
155
|
|
|
{ |
156
|
|
|
if ($this->fileHandle) { |
157
|
|
|
return fstat($this->fileHandle); |
158
|
|
|
} elseif (!is_resource($this->fileHandle) && is_dir($this->path)) { |
159
|
|
|
return stat($this->path); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
return false; |
|
|
|
|
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* {@inheritdoc} |
167
|
|
|
*/ |
168
|
|
|
public function cast($castAs) |
169
|
|
|
{ |
170
|
|
|
if ($this->fileHandle) { |
171
|
|
|
return $this->fileHandle; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
return false; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* {@inheritdoc} |
179
|
|
|
*/ |
180
|
|
|
public function unlink() |
181
|
|
|
{ |
182
|
|
|
if ($this->mode && $this->mode->impliesExistingContentDeletion()) { |
183
|
|
|
return @unlink($this->path); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
return false; |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.