TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
FileStreamWrapper.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Tests;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
59 {
63  protected $dirHandle = null;
64 
68  protected $fileHandle = null;
69 
75  protected static $registered = false;
76 
82  protected static $overlayPaths = [];
83 
89  protected static $rootPath = '';
90 
97  public static function init($rootPath)
98  {
99  self::$rootPath = rtrim(str_replace('\\', '/', $rootPath), '/') . '/';
100  self::register();
101  }
102 
107  public static function destroy()
108  {
109  self::$overlayPaths = [];
110  self::$rootPath = '';
111  if (self::$registered) {
112  self::restore();
113  }
114  }
115 
124  public static function registerOverlayPath($overlay, $replace, $createFolder = true)
125  {
126  $overlay = trim(str_replace('\\', '/', $overlay), '/') . '/';
127  $replace = rtrim(str_replace('\\', '/', $replace), '/') . '/';
128  self::$overlayPaths[$overlay] = $replace;
129  if ($createFolder) {
130  mkdir($replace);
131  }
132  }
133 
140  protected static function overlayPath($path)
141  {
142  $path = str_replace('\\', '/', $path);
143  $hasOverlay = false;
144  if (strpos($path, self::$rootPath) !== 0) {
145  // Path is not below root path, ignore it
146  return $path;
147  }
148 
149  $newPath = ltrim(substr($path, strlen(self::$rootPath)), '/');
150  foreach (self::$overlayPaths as $overlay => $replace) {
151  if (strpos($newPath, $overlay) === 0) {
152  $newPath = $replace . substr($newPath, strlen($overlay));
153  $hasOverlay = true;
154  break;
155  }
156  }
157  return $hasOverlay ? $newPath : $path;
158  }
159 
170  protected static function register()
171  {
172  if (self::$registered) {
173  return;
174  }
175 
176  if (@stream_wrapper_unregister('file') === false) {
177  throw new \BadFunctionCallException('Cannot unregister file:// stream wrapper.', 1396340331);
178  }
179  if (@stream_wrapper_register('file', __CLASS__) === false) {
180  throw new \BadFunctionCallException('A handler has already been registered for the file:// scheme.', 1396340332);
181  }
182 
183  self::$registered = true;
184  }
185 
191  protected static function restore()
192  {
193  if (!self::$registered) {
194  return;
195  }
196  if (@stream_wrapper_restore('file') === false) {
197  throw new \BadFunctionCallException('Cannot restore the default file:// stream handler.', 1396340333);
198  }
199  self::$registered = false;
200  }
201 
202  /*
203  * The following list of functions is implemented as of
204  * @see http://www.php.net/manual/en/streamwrapper.dir-closedir.php
205  */
206 
212  public function dir_closedir()
213  {
214  if ($this->dirHandle === null) {
215  return false;
216  } else {
217  self::restore();
218  closedir($this->dirHandle);
219  self::register();
220  $this->dirHandle = null;
221  return true;
222  }
223  }
224 
232  public function dir_opendir($path, $options = 0)
233  {
234  if ($this->dirHandle !== null) {
235  return false;
236  }
237  self::restore();
238  $path = self::overlayPath($path);
239  $this->dirHandle = opendir($path);
240  self::register();
241  return $this->dirHandle !== false;
242  }
243 
249  public function dir_readdir()
250  {
251  if ($this->dirHandle === null) {
252  return false;
253  }
254  self::restore();
255  $success = readdir($this->dirHandle);
256  self::register();
257  return $success;
258  }
259 
265  public function dir_rewinddir()
266  {
267  if ($this->dirHandle === null) {
268  return false;
269  }
270  self::restore();
271  rewinddir($this->dirHandle);
272  self::register();
273  return true;
274  }
275 
284  public function mkdir($path, $mode, $options = 0)
285  {
286  self::restore();
287  $path = self::overlayPath($path);
288  $success = mkdir($path, $mode, (bool)($options & STREAM_MKDIR_RECURSIVE));
289  self::register();
290  return $success;
291  }
292 
300  public function rename($pathFrom, $pathTo)
301  {
302  self::restore();
303  $pathFrom = self::overlayPath($pathFrom);
304  $pathTo = self::overlayPath($pathTo);
305  $success = rename($pathFrom, $pathTo);
306  self::register();
307  return $success;
308  }
309 
316  public function rmdir($path)
317  {
318  self::restore();
319  $path = self::overlayPath($path);
320  $success = rmdir($path);
321  self::register();
322  return $success;
323  }
324 
333  public function stream_cast($castAs)
334  {
335  if ($this->fileHandle !== null && $castAs & STREAM_CAST_AS_STREAM) {
336  return $this->fileHandle;
337  } else {
338  return false;
339  }
340  }
341 
346  public function stream_close()
347  {
348  self::restore();
349  if ($this->fileHandle !== null) {
350  fclose($this->fileHandle);
351  $this->fileHandle = null;
352  }
353  self::register();
354  }
355 
361  public function stream_eof()
362  {
363  if ($this->fileHandle === null) {
364  return false;
365  }
366  self::restore();
367  $success = feof($this->fileHandle);
368  self::register();
369  return $success;
370  }
371 
377  public function stream_flush()
378  {
379  if ($this->fileHandle === null) {
380  return false;
381  }
382  self::restore();
383  $success = fflush($this->fileHandle);
384  self::register();
385  return $success;
386  }
387 
394  public function stream_lock($operation)
395  {
396  if ($this->fileHandle === null) {
397  return false;
398  }
399  self::restore();
400  $success = flock($this->fileHandle, $operation);
401  self::register();
402  return $success;
403  }
404 
413  public function stream_metadata($path, $options, $value)
414  {
415  self::restore();
416  $path = self::overlayPath($path);
417  switch ($options) {
418  case STREAM_META_TOUCH:
419  $success = touch($path, $value[0], $value[1]);
420  break;
421  case STREAM_META_OWNER_NAME:
422  // Fall through
423  case STREAM_META_OWNER:
424  $success = chown($path, $value);
425  break;
426  case STREAM_META_GROUP_NAME:
427  // Fall through
428  case STREAM_META_GROUP:
429  $success = chgrp($path, $value);
430  break;
431  case STREAM_META_ACCESS:
432  $success = chmod($path, $value);
433  break;
434  default:
435  $success = false;
436  }
437  self::register();
438  return $success;
439  }
440 
450  public function stream_open($path, $mode, $options, &$opened_path)
451  {
452  if ($this->fileHandle !== null) {
453  return false;
454  }
455  self::restore();
456  $path = self::overlayPath($path);
457  $this->fileHandle = fopen($path, $mode, (bool)($options & STREAM_USE_PATH));
458  self::register();
459  return $this->fileHandle !== false;
460  }
461 
468  public function stream_read($length)
469  {
470  if ($this->fileHandle === null) {
471  return false;
472  }
473  self::restore();
474  $content = fread($this->fileHandle, $length);
475  self::register();
476  return $content;
477  }
478 
486  public function stream_seek($offset, $whence = SEEK_SET)
487  {
488  if ($this->fileHandle === null) {
489  return false;
490  }
491  self::restore();
492  $success = fseek($this->fileHandle, $offset, $whence);
493  self::register();
494  return $success;
495  }
496 
505  public function stream_set_option($option, $arg1, $arg2)
506  {
507  return false;
508  }
509 
515  public function stream_stat()
516  {
517  if ($this->fileHandle === null) {
518  return false;
519  }
520  self::restore();
521  $stats = fstat($this->fileHandle);
522  self::register();
523  return $stats;
524  }
525 
531  public function stream_tell()
532  {
533  if ($this->fileHandle === null) {
534  return false;
535  }
536  self::restore();
537  $position = ftell($this->fileHandle);
538  self::register();
539  return $position;
540  }
541 
548  public function stream_truncate($size)
549  {
550  if ($this->fileHandle === null) {
551  return false;
552  }
553  self::restore();
554  $success = ftruncate($this->fileHandle, $size);
555  self::register();
556  return $success;
557  }
558 
565  public function stream_write($data)
566  {
567  if ($this->fileHandle === null) {
568  return false;
569  }
570  self::restore();
571  $length = fwrite($this->fileHandle, $data);
572  self::register();
573  return $length;
574  }
575 
582  public function unlink($path)
583  {
584  self::restore();
585  $path = self::overlayPath($path);
586  $success = unlink($path);
587  self::register();
588  return $success;
589  }
590 
598  public function url_stat($path, $flags)
599  {
600  self::restore();
601  $path = self::overlayPath($path);
602  if ($flags & STREAM_URL_STAT_LINK) {
603  $information = @lstat($path);
604  } else {
605  $information = @stat($path);
606  }
607  self::register();
608  return $information;
609  }
610 }
static registerOverlayPath($overlay, $replace, $createFolder=true)
stream_open($path, $mode, $options, &$opened_path)
stream_seek($offset, $whence=SEEK_SET)