MediaWiki  master
TempFSFile.php
Go to the documentation of this file.
1 <?php
2 
4 
28 
35 class TempFSFile extends FSFile {
37  protected $canDelete = false;
38 
40  protected static $pathsCollect = null;
41 
47  public function __construct( $path ) {
48  parent::__construct( $path );
49 
50  if ( self::$pathsCollect === null ) {
51  // @codeCoverageIgnoreStart
52  self::$pathsCollect = [];
53  register_shutdown_function( [ __CLASS__, 'purgeAllOnShutdown' ] );
54  // @codeCoverageIgnoreEnd
55  }
56  }
57 
69  public static function factory( $prefix, $extension = '', $tmpDirectory = null ) {
70  return ( new TempFSFileFactory( $tmpDirectory ) )->newTempFSFile( $prefix, $extension );
71  }
72 
80  public static function getUsableTempDirectory() {
81  $tmpDir = array_map( 'getenv', [ 'TMPDIR', 'TMP', 'TEMP' ] );
82  $tmpDir[] = sys_get_temp_dir();
83  $tmpDir[] = ini_get( 'upload_tmp_dir' );
84  foreach ( $tmpDir as $tmp ) {
85  if ( $tmp != '' && is_dir( $tmp ) && is_writable( $tmp ) ) {
86  return $tmp;
87  }
88  }
89 
90  // PHP on Windows will detect C:\Windows\Temp as not writable even though PHP can write to
91  // it so create a directory within that called 'mwtmp' with a suffix of the user running
92  // the current process.
93  // The user is included as if various scripts are run by different users they will likely
94  // not be able to access each others temporary files.
95  if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
96  $tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mwtmp-' . get_current_user();
97  if ( !is_dir( $tmp ) ) {
98  mkdir( $tmp );
99  }
100  if ( is_dir( $tmp ) && is_writable( $tmp ) ) {
101  return $tmp;
102  }
103  }
104 
105  throw new RuntimeException(
106  'No writable temporary directory could be found. ' .
107  'Please explicitly specify a writable directory in configuration.' );
108  }
109 
115  public function purge() {
116  $this->canDelete = false; // done
117  AtEase::suppressWarnings();
118  $ok = unlink( $this->path );
119  AtEase::restoreWarnings();
120 
121  unset( self::$pathsCollect[$this->path] );
122 
123  return $ok;
124  }
125 
132  public function bind( $object ) {
133  if ( is_object( $object ) ) {
134  if ( !isset( $object->tempFSFileReferences ) ) {
135  // Init first since $object might use __get() and return only a copy variable
136  $object->tempFSFileReferences = [];
137  }
138  $object->tempFSFileReferences[] = $this;
139  }
140 
141  return $this;
142  }
143 
149  public function preserve() {
150  $this->canDelete = false;
151 
152  unset( self::$pathsCollect[$this->path] );
153 
154  return $this;
155  }
156 
162  public function autocollect() {
163  $this->canDelete = true;
164 
165  self::$pathsCollect[$this->path] = 1;
166 
167  return $this;
168  }
169 
177  public static function purgeAllOnShutdown() {
178  foreach ( self::$pathsCollect as $path => $unused ) {
179  AtEase::suppressWarnings();
180  unlink( $path );
181  AtEase::restoreWarnings();
182  }
183  }
184 
188  function __destruct() {
189  if ( $this->canDelete ) {
190  $this->purge();
191  }
192  }
193 }
string $path
Path to file.
Definition: FSFile.php:34
bind( $object)
Clean up the temporary file only after an object goes out of scope.
Definition: TempFSFile.php:132
bool $canDelete
Garbage collect the temp file.
Definition: TempFSFile.php:37
autocollect()
Set flag clean up after the temporary file.
Definition: TempFSFile.php:162
__destruct()
Cleans up after the temporary file by deleting it.
Definition: TempFSFile.php:188
static getUsableTempDirectory()
Definition: TempFSFile.php:80
static factory( $prefix, $extension='', $tmpDirectory=null)
Make a new temporary file on the file system.
Definition: TempFSFile.php:69
static array $pathsCollect
Map of (path => 1) for paths to delete on shutdown.
Definition: TempFSFile.php:40
__construct( $path)
Do not call directly.
Definition: TempFSFile.php:47
preserve()
Set flag to not clean up after the temporary file.
Definition: TempFSFile.php:149
purge()
Purge this file off the file system.
Definition: TempFSFile.php:115
static purgeAllOnShutdown()
Try to make sure that all files are purged on error.
Definition: TempFSFile.php:177
Class representing a non-directory file on the file system.
Definition: FSFile.php:32