MediaWiki  1.34.0
UploadedFileStream.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use Exception;
6 use Psr\Http\Message\StreamInterface;
7 use RuntimeException;
8 use Throwable;
9 use Wikimedia\AtEase\AtEase;
10 
21 class UploadedFileStream implements StreamInterface {
22 
24  private $fp;
25 
27  private $size = false;
28 
38  private static function quietCall( callable $func, array $args, $fail, $msg ) {
39  // TODO remove the function_exists check once we drop HHVM support
40  if ( function_exists( 'error_clear_last' ) ) {
41  error_clear_last();
42  }
43  $ret = AtEase::quietCall( $func, ...$args );
44  if ( $ret === $fail ) {
45  $err = error_get_last();
46  throw new RuntimeException( "$msg: " . ( $err['message'] ?? 'Unknown error' ) );
47  }
48  return $ret;
49  }
50 
54  public function __construct( $filename ) {
55  $this->fp = self::quietCall( 'fopen', [ $filename, 'r' ], false, 'Failed to open file' );
56  }
57 
62  private function checkOpen() {
63  if ( !$this->fp ) {
64  throw new RuntimeException( 'Stream is not open' );
65  }
66  }
67 
68  public function __destruct() {
69  $this->close();
70  }
71 
72  public function __toString() {
73  try {
74  $this->seek( 0 );
75  return $this->getContents();
76  } catch ( Exception $ex ) {
77  // Not allowed to throw
78  return '';
79  } catch ( Throwable $ex ) {
80  // Not allowed to throw
81  return '';
82  }
83  }
84 
85  public function close() {
86  if ( $this->fp ) {
87  // Spec doesn't care about close errors.
88  AtEase::quietCall( 'fclose', $this->fp );
89  $this->fp = null;
90  }
91  }
92 
93  public function detach() {
94  $ret = $this->fp;
95  $this->fp = null;
96  return $ret;
97  }
98 
99  public function getSize() {
100  if ( $this->size === false ) {
101  $this->size = null;
102 
103  if ( $this->fp ) {
104  // Spec doesn't care about errors here.
105  $stat = AtEase::quietCall( 'fstat', $this->fp );
106  $this->size = $stat['size'] ?? null;
107  }
108  }
109 
110  return $this->size;
111  }
112 
113  public function tell() {
114  $this->checkOpen();
115  return self::quietCall( 'ftell', [ $this->fp ], -1, 'Cannot determine stream position' );
116  }
117 
118  public function eof() {
119  // Spec doesn't care about errors here.
120  return !$this->fp || AtEase::quietCall( 'feof', $this->fp );
121  }
122 
123  public function isSeekable() {
124  return (bool)$this->fp;
125  }
126 
127  public function seek( $offset, $whence = SEEK_SET ) {
128  $this->checkOpen();
129  self::quietCall( 'fseek', [ $this->fp, $offset, $whence ], -1, 'Seek failed' );
130  }
131 
132  public function rewind() {
133  $this->seek( 0 );
134  }
135 
136  public function isWritable() {
137  return false;
138  }
139 
140  public function write( $string ) {
141  $this->checkOpen();
142  throw new RuntimeException( 'Stream is read-only' );
143  }
144 
145  public function isReadable() {
146  return (bool)$this->fp;
147  }
148 
149  public function read( $length ) {
150  $this->checkOpen();
151  return self::quietCall( 'fread', [ $this->fp, $length ], false, 'Read failed' );
152  }
153 
154  public function getContents() {
155  $this->checkOpen();
156  return self::quietCall( 'stream_get_contents', [ $this->fp ], false, 'Read failed' );
157  }
158 
159  public function getMetadata( $key = null ) {
160  $this->checkOpen();
161  $ret = self::quietCall( 'stream_get_meta_data', [ $this->fp ], false, 'Metadata fetch failed' );
162  if ( $key !== null ) {
163  $ret = $ret[$key] ?? null;
164  }
165  return $ret;
166  }
167 
168 }
Wikimedia\ParamValidator\Util\UploadedFileStream\quietCall
static quietCall(callable $func, array $args, $fail, $msg)
Call, throwing on error.
Definition: UploadedFileStream.php:38
Wikimedia\ParamValidator\Util\UploadedFileStream\rewind
rewind()
Definition: UploadedFileStream.php:132
Wikimedia\ParamValidator\Util\UploadedFileStream\read
read( $length)
Definition: UploadedFileStream.php:149
Wikimedia\ParamValidator\Util\UploadedFileStream
Implementation of StreamInterface for a file in $_FILES.
Definition: UploadedFileStream.php:21
Wikimedia\ParamValidator\Util\UploadedFileStream\isWritable
isWritable()
Definition: UploadedFileStream.php:136
Wikimedia\ParamValidator\Util\UploadedFileStream\$fp
resource $fp
File handle.
Definition: UploadedFileStream.php:24
Wikimedia\ParamValidator\Util\UploadedFileStream\detach
detach()
Definition: UploadedFileStream.php:93
Wikimedia\ParamValidator\Util\UploadedFileStream\checkOpen
checkOpen()
Check if the stream is open.
Definition: UploadedFileStream.php:62
Wikimedia\ParamValidator\Util\UploadedFileStream\getMetadata
getMetadata( $key=null)
Definition: UploadedFileStream.php:159
Wikimedia\ParamValidator\Util\UploadedFileStream\$size
int false null $size
File size.
Definition: UploadedFileStream.php:27
Wikimedia\ParamValidator\Util\UploadedFileStream\seek
seek( $offset, $whence=SEEK_SET)
Definition: UploadedFileStream.php:127
Wikimedia\ParamValidator\Util\UploadedFileStream\getSize
getSize()
Definition: UploadedFileStream.php:99
Wikimedia\ParamValidator\Util\UploadedFileStream\isSeekable
isSeekable()
Definition: UploadedFileStream.php:123
Wikimedia\ParamValidator\Util\UploadedFileStream\eof
eof()
Definition: UploadedFileStream.php:118
Wikimedia\ParamValidator\Util\UploadedFileStream\__toString
__toString()
Definition: UploadedFileStream.php:72
Wikimedia\ParamValidator\Util\UploadedFileStream\__construct
__construct( $filename)
Definition: UploadedFileStream.php:54
$args
if( $line===false) $args
Definition: cdb.php:64
Wikimedia\ParamValidator\Util\UploadedFileStream\tell
tell()
Definition: UploadedFileStream.php:113
Wikimedia\ParamValidator\Util
Definition: UploadedFile.php:3
Wikimedia\ParamValidator\Util\UploadedFileStream\close
close()
Definition: UploadedFileStream.php:85
Wikimedia\ParamValidator\Util\UploadedFileStream\getContents
getContents()
Definition: UploadedFileStream.php:154
Wikimedia\ParamValidator\Util\UploadedFileStream\write
write( $string)
Definition: UploadedFileStream.php:140
Wikimedia\ParamValidator\Util\UploadedFileStream\__destruct
__destruct()
Definition: UploadedFileStream.php:68
Wikimedia\ParamValidator\Util\UploadedFileStream\isReadable
isReadable()
Definition: UploadedFileStream.php:145