Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\StreamWrapper;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * Defines a Drupal stream wrapper base class for local files.
|
Chris@0
|
7 *
|
Chris@0
|
8 * This class provides a complete stream wrapper implementation. URIs such as
|
Chris@0
|
9 * "public://example.txt" are expanded to a normal filesystem path such as
|
Chris@0
|
10 * "sites/default/files/example.txt" and then PHP filesystem functions are
|
Chris@0
|
11 * invoked.
|
Chris@0
|
12 *
|
Chris@0
|
13 * Drupal\Core\StreamWrapper\LocalStream implementations need to implement at least the
|
Chris@0
|
14 * getDirectoryPath() and getExternalUrl() methods.
|
Chris@0
|
15 */
|
Chris@0
|
16 abstract class LocalStream implements StreamWrapperInterface {
|
Chris@0
|
17 /**
|
Chris@0
|
18 * Stream context resource.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @var resource
|
Chris@0
|
21 */
|
Chris@0
|
22 public $context;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * A generic resource handle.
|
Chris@0
|
26 *
|
Chris@0
|
27 * @var resource
|
Chris@0
|
28 */
|
Chris@0
|
29 public $handle = NULL;
|
Chris@0
|
30
|
Chris@0
|
31 /**
|
Chris@0
|
32 * Instance URI (stream).
|
Chris@0
|
33 *
|
Chris@0
|
34 * A stream is referenced as "scheme://target".
|
Chris@0
|
35 *
|
Chris@0
|
36 * @var string
|
Chris@0
|
37 */
|
Chris@0
|
38 protected $uri;
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * {@inheritdoc}
|
Chris@0
|
42 */
|
Chris@0
|
43 public static function getType() {
|
Chris@0
|
44 return StreamWrapperInterface::NORMAL;
|
Chris@0
|
45 }
|
Chris@0
|
46
|
Chris@0
|
47 /**
|
Chris@0
|
48 * Gets the path that the wrapper is responsible for.
|
Chris@0
|
49 *
|
Chris@0
|
50 * @todo Review this method name in D8 per https://www.drupal.org/node/701358.
|
Chris@0
|
51 *
|
Chris@0
|
52 * @return string
|
Chris@0
|
53 * String specifying the path.
|
Chris@0
|
54 */
|
Chris@0
|
55 abstract public function getDirectoryPath();
|
Chris@0
|
56
|
Chris@0
|
57 /**
|
Chris@0
|
58 * {@inheritdoc}
|
Chris@0
|
59 */
|
Chris@0
|
60 public function setUri($uri) {
|
Chris@0
|
61 $this->uri = $uri;
|
Chris@0
|
62 }
|
Chris@0
|
63
|
Chris@0
|
64 /**
|
Chris@0
|
65 * {@inheritdoc}
|
Chris@0
|
66 */
|
Chris@0
|
67 public function getUri() {
|
Chris@0
|
68 return $this->uri;
|
Chris@0
|
69 }
|
Chris@0
|
70
|
Chris@0
|
71 /**
|
Chris@0
|
72 * Returns the local writable target of the resource within the stream.
|
Chris@0
|
73 *
|
Chris@0
|
74 * This function should be used in place of calls to realpath() or similar
|
Chris@0
|
75 * functions when attempting to determine the location of a file. While
|
Chris@0
|
76 * functions like realpath() may return the location of a read-only file, this
|
Chris@0
|
77 * method may return a URI or path suitable for writing that is completely
|
Chris@0
|
78 * separate from the URI used for reading.
|
Chris@0
|
79 *
|
Chris@0
|
80 * @param string $uri
|
Chris@0
|
81 * Optional URI.
|
Chris@0
|
82 *
|
Chris@0
|
83 * @return string|bool
|
Chris@0
|
84 * Returns a string representing a location suitable for writing of a file,
|
Chris@0
|
85 * or FALSE if unable to write to the file such as with read-only streams.
|
Chris@0
|
86 */
|
Chris@0
|
87 protected function getTarget($uri = NULL) {
|
Chris@0
|
88 if (!isset($uri)) {
|
Chris@0
|
89 $uri = $this->uri;
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 list(, $target) = explode('://', $uri, 2);
|
Chris@0
|
93
|
Chris@0
|
94 // Remove erroneous leading or trailing, forward-slashes and backslashes.
|
Chris@0
|
95 return trim($target, '\/');
|
Chris@0
|
96 }
|
Chris@0
|
97
|
Chris@0
|
98 /**
|
Chris@0
|
99 * {@inheritdoc}
|
Chris@0
|
100 */
|
Chris@0
|
101 public function realpath() {
|
Chris@0
|
102 return $this->getLocalPath();
|
Chris@0
|
103 }
|
Chris@0
|
104
|
Chris@0
|
105 /**
|
Chris@0
|
106 * Returns the canonical absolute path of the URI, if possible.
|
Chris@0
|
107 *
|
Chris@0
|
108 * @param string $uri
|
Chris@0
|
109 * (optional) The stream wrapper URI to be converted to a canonical
|
Chris@0
|
110 * absolute path. This may point to a directory or another type of file.
|
Chris@0
|
111 *
|
Chris@0
|
112 * @return string|bool
|
Chris@0
|
113 * If $uri is not set, returns the canonical absolute path of the URI
|
Chris@0
|
114 * previously set by the
|
Chris@0
|
115 * Drupal\Core\StreamWrapper\StreamWrapperInterface::setUri() function.
|
Chris@0
|
116 * If $uri is set and valid for this class, returns its canonical absolute
|
Chris@0
|
117 * path, as determined by the realpath() function. If $uri is set but not
|
Chris@0
|
118 * valid, returns FALSE.
|
Chris@0
|
119 */
|
Chris@0
|
120 protected function getLocalPath($uri = NULL) {
|
Chris@0
|
121 if (!isset($uri)) {
|
Chris@0
|
122 $uri = $this->uri;
|
Chris@0
|
123 }
|
Chris@0
|
124 $path = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
|
Chris@0
|
125
|
Chris@0
|
126 // In PHPUnit tests, the base path for local streams may be a virtual
|
Chris@0
|
127 // filesystem stream wrapper URI, in which case this local stream acts like
|
Chris@0
|
128 // a proxy. realpath() is not supported by vfsStream, because a virtual
|
Chris@0
|
129 // file system does not have a real filepath.
|
Chris@0
|
130 if (strpos($path, 'vfs://') === 0) {
|
Chris@0
|
131 return $path;
|
Chris@0
|
132 }
|
Chris@0
|
133
|
Chris@0
|
134 $realpath = realpath($path);
|
Chris@0
|
135 if (!$realpath) {
|
Chris@0
|
136 // This file does not yet exist.
|
Chris@18
|
137 $realpath = realpath(dirname($path)) . '/' . \Drupal::service('file_system')->basename($path);
|
Chris@0
|
138 }
|
Chris@0
|
139 $directory = realpath($this->getDirectoryPath());
|
Chris@0
|
140 if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
|
Chris@0
|
141 return FALSE;
|
Chris@0
|
142 }
|
Chris@0
|
143 return $realpath;
|
Chris@0
|
144 }
|
Chris@0
|
145
|
Chris@0
|
146 /**
|
Chris@0
|
147 * Support for fopen(), file_get_contents(), file_put_contents() etc.
|
Chris@0
|
148 *
|
Chris@0
|
149 * @param string $uri
|
Chris@0
|
150 * A string containing the URI to the file to open.
|
Chris@0
|
151 * @param int $mode
|
Chris@0
|
152 * The file mode ("r", "wb" etc.).
|
Chris@0
|
153 * @param int $options
|
Chris@0
|
154 * A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
|
Chris@0
|
155 * @param string $opened_path
|
Chris@0
|
156 * A string containing the path actually opened.
|
Chris@0
|
157 *
|
Chris@0
|
158 * @return bool
|
Chris@0
|
159 * Returns TRUE if file was opened successfully.
|
Chris@0
|
160 *
|
Chris@0
|
161 * @see http://php.net/manual/streamwrapper.stream-open.php
|
Chris@0
|
162 */
|
Chris@0
|
163 public function stream_open($uri, $mode, $options, &$opened_path) {
|
Chris@0
|
164 $this->uri = $uri;
|
Chris@0
|
165 $path = $this->getLocalPath();
|
Chris@0
|
166 $this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
|
Chris@0
|
167
|
Chris@0
|
168 if ((bool) $this->handle && $options & STREAM_USE_PATH) {
|
Chris@0
|
169 $opened_path = $path;
|
Chris@0
|
170 }
|
Chris@0
|
171
|
Chris@0
|
172 return (bool) $this->handle;
|
Chris@0
|
173 }
|
Chris@0
|
174
|
Chris@0
|
175 /**
|
Chris@0
|
176 * Support for flock().
|
Chris@0
|
177 *
|
Chris@0
|
178 * @param int $operation
|
Chris@0
|
179 * One of the following:
|
Chris@0
|
180 * - LOCK_SH to acquire a shared lock (reader).
|
Chris@0
|
181 * - LOCK_EX to acquire an exclusive lock (writer).
|
Chris@0
|
182 * - LOCK_UN to release a lock (shared or exclusive).
|
Chris@0
|
183 * - LOCK_NB if you don't want flock() to block while locking (not
|
Chris@0
|
184 * supported on Windows).
|
Chris@0
|
185 *
|
Chris@0
|
186 * @return bool
|
Chris@0
|
187 * Always returns TRUE at the present time.
|
Chris@0
|
188 *
|
Chris@0
|
189 * @see http://php.net/manual/streamwrapper.stream-lock.php
|
Chris@0
|
190 */
|
Chris@0
|
191 public function stream_lock($operation) {
|
Chris@0
|
192 if (in_array($operation, [LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB])) {
|
Chris@0
|
193 return flock($this->handle, $operation);
|
Chris@0
|
194 }
|
Chris@0
|
195
|
Chris@0
|
196 return TRUE;
|
Chris@0
|
197 }
|
Chris@0
|
198
|
Chris@0
|
199 /**
|
Chris@0
|
200 * Support for fread(), file_get_contents() etc.
|
Chris@0
|
201 *
|
Chris@0
|
202 * @param int $count
|
Chris@0
|
203 * Maximum number of bytes to be read.
|
Chris@0
|
204 *
|
Chris@0
|
205 * @return string|bool
|
Chris@0
|
206 * The string that was read, or FALSE in case of an error.
|
Chris@0
|
207 *
|
Chris@0
|
208 * @see http://php.net/manual/streamwrapper.stream-read.php
|
Chris@0
|
209 */
|
Chris@0
|
210 public function stream_read($count) {
|
Chris@0
|
211 return fread($this->handle, $count);
|
Chris@0
|
212 }
|
Chris@0
|
213
|
Chris@0
|
214 /**
|
Chris@0
|
215 * Support for fwrite(), file_put_contents() etc.
|
Chris@0
|
216 *
|
Chris@0
|
217 * @param string $data
|
Chris@0
|
218 * The string to be written.
|
Chris@0
|
219 *
|
Chris@0
|
220 * @return int
|
Chris@0
|
221 * The number of bytes written.
|
Chris@0
|
222 *
|
Chris@0
|
223 * @see http://php.net/manual/streamwrapper.stream-write.php
|
Chris@0
|
224 */
|
Chris@0
|
225 public function stream_write($data) {
|
Chris@0
|
226 return fwrite($this->handle, $data);
|
Chris@0
|
227 }
|
Chris@0
|
228
|
Chris@0
|
229 /**
|
Chris@0
|
230 * Support for feof().
|
Chris@0
|
231 *
|
Chris@0
|
232 * @return bool
|
Chris@0
|
233 * TRUE if end-of-file has been reached.
|
Chris@0
|
234 *
|
Chris@0
|
235 * @see http://php.net/manual/streamwrapper.stream-eof.php
|
Chris@0
|
236 */
|
Chris@0
|
237 public function stream_eof() {
|
Chris@0
|
238 return feof($this->handle);
|
Chris@0
|
239 }
|
Chris@0
|
240
|
Chris@0
|
241 /**
|
Chris@0
|
242 * {@inheritdoc}
|
Chris@0
|
243 */
|
Chris@0
|
244 public function stream_seek($offset, $whence = SEEK_SET) {
|
Chris@0
|
245 // fseek returns 0 on success and -1 on a failure.
|
Chris@0
|
246 // stream_seek 1 on success and 0 on a failure.
|
Chris@0
|
247 return !fseek($this->handle, $offset, $whence);
|
Chris@0
|
248 }
|
Chris@0
|
249
|
Chris@0
|
250 /**
|
Chris@0
|
251 * Support for fflush().
|
Chris@0
|
252 *
|
Chris@0
|
253 * @return bool
|
Chris@0
|
254 * TRUE if data was successfully stored (or there was no data to store).
|
Chris@0
|
255 *
|
Chris@0
|
256 * @see http://php.net/manual/streamwrapper.stream-flush.php
|
Chris@0
|
257 */
|
Chris@0
|
258 public function stream_flush() {
|
Chris@0
|
259 return fflush($this->handle);
|
Chris@0
|
260 }
|
Chris@0
|
261
|
Chris@0
|
262 /**
|
Chris@0
|
263 * Support for ftell().
|
Chris@0
|
264 *
|
Chris@0
|
265 * @return bool
|
Chris@0
|
266 * The current offset in bytes from the beginning of file.
|
Chris@0
|
267 *
|
Chris@0
|
268 * @see http://php.net/manual/streamwrapper.stream-tell.php
|
Chris@0
|
269 */
|
Chris@0
|
270 public function stream_tell() {
|
Chris@0
|
271 return ftell($this->handle);
|
Chris@0
|
272 }
|
Chris@0
|
273
|
Chris@0
|
274 /**
|
Chris@0
|
275 * Support for fstat().
|
Chris@0
|
276 *
|
Chris@0
|
277 * @return bool
|
Chris@0
|
278 * An array with file status, or FALSE in case of an error - see fstat()
|
Chris@0
|
279 * for a description of this array.
|
Chris@0
|
280 *
|
Chris@0
|
281 * @see http://php.net/manual/streamwrapper.stream-stat.php
|
Chris@0
|
282 */
|
Chris@0
|
283 public function stream_stat() {
|
Chris@0
|
284 return fstat($this->handle);
|
Chris@0
|
285 }
|
Chris@0
|
286
|
Chris@0
|
287 /**
|
Chris@0
|
288 * Support for fclose().
|
Chris@0
|
289 *
|
Chris@0
|
290 * @return bool
|
Chris@0
|
291 * TRUE if stream was successfully closed.
|
Chris@0
|
292 *
|
Chris@0
|
293 * @see http://php.net/manual/streamwrapper.stream-close.php
|
Chris@0
|
294 */
|
Chris@0
|
295 public function stream_close() {
|
Chris@0
|
296 return fclose($this->handle);
|
Chris@0
|
297 }
|
Chris@0
|
298
|
Chris@0
|
299 /**
|
Chris@0
|
300 * {@inheritdoc}
|
Chris@0
|
301 */
|
Chris@0
|
302 public function stream_cast($cast_as) {
|
Chris@0
|
303 return $this->handle ? $this->handle : FALSE;
|
Chris@0
|
304 }
|
Chris@0
|
305
|
Chris@0
|
306 /**
|
Chris@0
|
307 * {@inheritdoc}
|
Chris@0
|
308 */
|
Chris@0
|
309 public function stream_metadata($uri, $option, $value) {
|
Chris@0
|
310 $target = $this->getLocalPath($uri);
|
Chris@0
|
311 $return = FALSE;
|
Chris@0
|
312 switch ($option) {
|
Chris@0
|
313 case STREAM_META_TOUCH:
|
Chris@0
|
314 if (!empty($value)) {
|
Chris@0
|
315 $return = touch($target, $value[0], $value[1]);
|
Chris@0
|
316 }
|
Chris@0
|
317 else {
|
Chris@0
|
318 $return = touch($target);
|
Chris@0
|
319 }
|
Chris@0
|
320 break;
|
Chris@0
|
321
|
Chris@0
|
322 case STREAM_META_OWNER_NAME:
|
Chris@0
|
323 case STREAM_META_OWNER:
|
Chris@0
|
324 $return = chown($target, $value);
|
Chris@0
|
325 break;
|
Chris@0
|
326
|
Chris@0
|
327 case STREAM_META_GROUP_NAME:
|
Chris@0
|
328 case STREAM_META_GROUP:
|
Chris@0
|
329 $return = chgrp($target, $value);
|
Chris@0
|
330 break;
|
Chris@0
|
331
|
Chris@0
|
332 case STREAM_META_ACCESS:
|
Chris@0
|
333 $return = chmod($target, $value);
|
Chris@0
|
334 break;
|
Chris@0
|
335 }
|
Chris@0
|
336 if ($return) {
|
Chris@0
|
337 // For convenience clear the file status cache of the underlying file,
|
Chris@0
|
338 // since metadata operations are often followed by file status checks.
|
Chris@0
|
339 clearstatcache(TRUE, $target);
|
Chris@0
|
340 }
|
Chris@0
|
341 return $return;
|
Chris@0
|
342 }
|
Chris@0
|
343
|
Chris@0
|
344 /**
|
Chris@0
|
345 * {@inheritdoc}
|
Chris@0
|
346 *
|
Chris@0
|
347 * Since Windows systems do not allow it and it is not needed for most use
|
Chris@0
|
348 * cases anyway, this method is not supported on local files and will trigger
|
Chris@0
|
349 * an error and return false. If needed, custom subclasses can provide
|
Chris@0
|
350 * OS-specific implementations for advanced use cases.
|
Chris@0
|
351 */
|
Chris@0
|
352 public function stream_set_option($option, $arg1, $arg2) {
|
Chris@0
|
353 trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
|
Chris@0
|
354 return FALSE;
|
Chris@0
|
355 }
|
Chris@0
|
356
|
Chris@0
|
357 /**
|
Chris@0
|
358 * {@inheritdoc}
|
Chris@0
|
359 */
|
Chris@0
|
360 public function stream_truncate($new_size) {
|
Chris@0
|
361 return ftruncate($this->handle, $new_size);
|
Chris@0
|
362 }
|
Chris@0
|
363
|
Chris@0
|
364 /**
|
Chris@0
|
365 * Support for unlink().
|
Chris@0
|
366 *
|
Chris@0
|
367 * @param string $uri
|
Chris@0
|
368 * A string containing the URI to the resource to delete.
|
Chris@0
|
369 *
|
Chris@0
|
370 * @return bool
|
Chris@0
|
371 * TRUE if resource was successfully deleted.
|
Chris@0
|
372 *
|
Chris@0
|
373 * @see http://php.net/manual/streamwrapper.unlink.php
|
Chris@0
|
374 */
|
Chris@0
|
375 public function unlink($uri) {
|
Chris@0
|
376 $this->uri = $uri;
|
Chris@0
|
377 return drupal_unlink($this->getLocalPath());
|
Chris@0
|
378 }
|
Chris@0
|
379
|
Chris@0
|
380 /**
|
Chris@0
|
381 * Support for rename().
|
Chris@0
|
382 *
|
Chris@0
|
383 * @param string $from_uri
|
Chris@0
|
384 * The URI to the file to rename.
|
Chris@0
|
385 * @param string $to_uri
|
Chris@0
|
386 * The new URI for file.
|
Chris@0
|
387 *
|
Chris@0
|
388 * @return bool
|
Chris@0
|
389 * TRUE if file was successfully renamed.
|
Chris@0
|
390 *
|
Chris@0
|
391 * @see http://php.net/manual/streamwrapper.rename.php
|
Chris@0
|
392 */
|
Chris@0
|
393 public function rename($from_uri, $to_uri) {
|
Chris@0
|
394 return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
|
Chris@0
|
395 }
|
Chris@0
|
396
|
Chris@0
|
397 /**
|
Chris@0
|
398 * Gets the name of the directory from a given path.
|
Chris@0
|
399 *
|
Chris@18
|
400 * This method is usually accessed through
|
Chris@18
|
401 * \Drupal\Core\File\FileSystemInterface::dirname(), which wraps around the
|
Chris@18
|
402 * PHP dirname() function because it does not support stream wrappers.
|
Chris@0
|
403 *
|
Chris@0
|
404 * @param string $uri
|
Chris@0
|
405 * A URI or path.
|
Chris@0
|
406 *
|
Chris@0
|
407 * @return string
|
Chris@0
|
408 * A string containing the directory name.
|
Chris@0
|
409 *
|
Chris@18
|
410 * @see \Drupal\Core\File\FileSystemInterface::dirname()
|
Chris@0
|
411 */
|
Chris@0
|
412 public function dirname($uri = NULL) {
|
Chris@0
|
413 list($scheme) = explode('://', $uri, 2);
|
Chris@0
|
414 $target = $this->getTarget($uri);
|
Chris@0
|
415 $dirname = dirname($target);
|
Chris@0
|
416
|
Chris@0
|
417 if ($dirname == '.') {
|
Chris@0
|
418 $dirname = '';
|
Chris@0
|
419 }
|
Chris@0
|
420
|
Chris@0
|
421 return $scheme . '://' . $dirname;
|
Chris@0
|
422 }
|
Chris@0
|
423
|
Chris@0
|
424 /**
|
Chris@0
|
425 * Support for mkdir().
|
Chris@0
|
426 *
|
Chris@0
|
427 * @param string $uri
|
Chris@0
|
428 * A string containing the URI to the directory to create.
|
Chris@0
|
429 * @param int $mode
|
Chris@0
|
430 * Permission flags - see mkdir().
|
Chris@0
|
431 * @param int $options
|
Chris@0
|
432 * A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
|
Chris@0
|
433 *
|
Chris@0
|
434 * @return bool
|
Chris@0
|
435 * TRUE if directory was successfully created.
|
Chris@0
|
436 *
|
Chris@0
|
437 * @see http://php.net/manual/streamwrapper.mkdir.php
|
Chris@0
|
438 */
|
Chris@0
|
439 public function mkdir($uri, $mode, $options) {
|
Chris@0
|
440 $this->uri = $uri;
|
Chris@0
|
441 $recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
|
Chris@0
|
442 if ($recursive) {
|
Chris@0
|
443 // $this->getLocalPath() fails if $uri has multiple levels of directories
|
Chris@0
|
444 // that do not yet exist.
|
Chris@0
|
445 $localpath = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
|
Chris@0
|
446 }
|
Chris@0
|
447 else {
|
Chris@0
|
448 $localpath = $this->getLocalPath($uri);
|
Chris@0
|
449 }
|
Chris@18
|
450 /** @var \Drupal\Core\File\FileSystemInterface $file_system */
|
Chris@18
|
451 $file_system = \Drupal::service('file_system');
|
Chris@0
|
452 if ($options & STREAM_REPORT_ERRORS) {
|
Chris@18
|
453 return $file_system->mkdir($localpath, $mode, $recursive);
|
Chris@0
|
454 }
|
Chris@0
|
455 else {
|
Chris@18
|
456 return @$file_system->mkdir($localpath, $mode, $recursive);
|
Chris@0
|
457 }
|
Chris@0
|
458 }
|
Chris@0
|
459
|
Chris@0
|
460 /**
|
Chris@0
|
461 * Support for rmdir().
|
Chris@0
|
462 *
|
Chris@0
|
463 * @param string $uri
|
Chris@0
|
464 * A string containing the URI to the directory to delete.
|
Chris@0
|
465 * @param int $options
|
Chris@0
|
466 * A bit mask of STREAM_REPORT_ERRORS.
|
Chris@0
|
467 *
|
Chris@0
|
468 * @return bool
|
Chris@0
|
469 * TRUE if directory was successfully removed.
|
Chris@0
|
470 *
|
Chris@0
|
471 * @see http://php.net/manual/streamwrapper.rmdir.php
|
Chris@0
|
472 */
|
Chris@0
|
473 public function rmdir($uri, $options) {
|
Chris@0
|
474 $this->uri = $uri;
|
Chris@18
|
475 /** @var \Drupal\Core\File\FileSystemInterface $file_system */
|
Chris@18
|
476 $file_system = \Drupal::service('file_system');
|
Chris@0
|
477 if ($options & STREAM_REPORT_ERRORS) {
|
Chris@18
|
478 return $file_system->rmdir($this->getLocalPath());
|
Chris@0
|
479 }
|
Chris@0
|
480 else {
|
Chris@18
|
481 return @$file_system->rmdir($this->getLocalPath());
|
Chris@0
|
482 }
|
Chris@0
|
483 }
|
Chris@0
|
484
|
Chris@0
|
485 /**
|
Chris@0
|
486 * Support for stat().
|
Chris@0
|
487 *
|
Chris@0
|
488 * @param string $uri
|
Chris@0
|
489 * A string containing the URI to get information about.
|
Chris@0
|
490 * @param int $flags
|
Chris@0
|
491 * A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
|
Chris@0
|
492 *
|
Chris@0
|
493 * @return array
|
Chris@0
|
494 * An array with file status, or FALSE in case of an error - see fstat()
|
Chris@0
|
495 * for a description of this array.
|
Chris@0
|
496 *
|
Chris@0
|
497 * @see http://php.net/manual/streamwrapper.url-stat.php
|
Chris@0
|
498 */
|
Chris@0
|
499 public function url_stat($uri, $flags) {
|
Chris@0
|
500 $this->uri = $uri;
|
Chris@0
|
501 $path = $this->getLocalPath();
|
Chris@0
|
502 // Suppress warnings if requested or if the file or directory does not
|
Chris@0
|
503 // exist. This is consistent with PHP's plain filesystem stream wrapper.
|
Chris@0
|
504 if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
|
Chris@0
|
505 return @stat($path);
|
Chris@0
|
506 }
|
Chris@0
|
507 else {
|
Chris@0
|
508 return stat($path);
|
Chris@0
|
509 }
|
Chris@0
|
510 }
|
Chris@0
|
511
|
Chris@0
|
512 /**
|
Chris@0
|
513 * Support for opendir().
|
Chris@0
|
514 *
|
Chris@0
|
515 * @param string $uri
|
Chris@0
|
516 * A string containing the URI to the directory to open.
|
Chris@0
|
517 * @param int $options
|
Chris@0
|
518 * Unknown (parameter is not documented in PHP Manual).
|
Chris@0
|
519 *
|
Chris@0
|
520 * @return bool
|
Chris@0
|
521 * TRUE on success.
|
Chris@0
|
522 *
|
Chris@0
|
523 * @see http://php.net/manual/streamwrapper.dir-opendir.php
|
Chris@0
|
524 */
|
Chris@0
|
525 public function dir_opendir($uri, $options) {
|
Chris@0
|
526 $this->uri = $uri;
|
Chris@0
|
527 $this->handle = opendir($this->getLocalPath());
|
Chris@0
|
528
|
Chris@0
|
529 return (bool) $this->handle;
|
Chris@0
|
530 }
|
Chris@0
|
531
|
Chris@0
|
532 /**
|
Chris@0
|
533 * Support for readdir().
|
Chris@0
|
534 *
|
Chris@0
|
535 * @return string
|
Chris@0
|
536 * The next filename, or FALSE if there are no more files in the directory.
|
Chris@0
|
537 *
|
Chris@0
|
538 * @see http://php.net/manual/streamwrapper.dir-readdir.php
|
Chris@0
|
539 */
|
Chris@0
|
540 public function dir_readdir() {
|
Chris@0
|
541 return readdir($this->handle);
|
Chris@0
|
542 }
|
Chris@0
|
543
|
Chris@0
|
544 /**
|
Chris@0
|
545 * Support for rewinddir().
|
Chris@0
|
546 *
|
Chris@0
|
547 * @return bool
|
Chris@0
|
548 * TRUE on success.
|
Chris@0
|
549 *
|
Chris@0
|
550 * @see http://php.net/manual/streamwrapper.dir-rewinddir.php
|
Chris@0
|
551 */
|
Chris@0
|
552 public function dir_rewinddir() {
|
Chris@0
|
553 rewinddir($this->handle);
|
Chris@0
|
554 // We do not really have a way to signal a failure as rewinddir() does not
|
Chris@0
|
555 // have a return value and there is no way to read a directory handler
|
Chris@0
|
556 // without advancing to the next file.
|
Chris@0
|
557 return TRUE;
|
Chris@0
|
558 }
|
Chris@0
|
559
|
Chris@0
|
560 /**
|
Chris@0
|
561 * Support for closedir().
|
Chris@0
|
562 *
|
Chris@0
|
563 * @return bool
|
Chris@0
|
564 * TRUE on success.
|
Chris@0
|
565 *
|
Chris@0
|
566 * @see http://php.net/manual/streamwrapper.dir-closedir.php
|
Chris@0
|
567 */
|
Chris@0
|
568 public function dir_closedir() {
|
Chris@0
|
569 closedir($this->handle);
|
Chris@0
|
570 // We do not really have a way to signal a failure as closedir() does not
|
Chris@0
|
571 // have a return value.
|
Chris@0
|
572 return TRUE;
|
Chris@0
|
573 }
|
Chris@0
|
574
|
Chris@0
|
575 }
|