Merged FileBackend branch. Manually avoiding merging the many prop-only changes SVN...
[lhc/web/wiklou.git] / includes / filerepo / file / TempFSFile.php
1 <?php
2 /**
3 * @file
4 * @ingroup FileRepo
5 * @ingroup FileBackend
6 */
7
8 /**
9 * This class is used to hold the location and do limited manipulation
10 * of files stored temporarily (usually this will be $wgTmpDirectory)
11 *
12 * @ingroup FileRepo
13 * @ingroup FileBackend
14 */
15 class TempFSFile extends FSFile {
16 protected $canDelete = true; // garbage collect the temp file
17
18 /** @var Array of active temp files to purge on shutdown */
19 protected static $instances = array();
20
21 /**
22 * Make a new temporary file on the file system.
23 * Temporary files may be purged when the file object falls out of scope.
24 *
25 * @param $prefix string
26 * @param $extension string
27 * @return TempFSFile|null
28 */
29 public static function factory( $prefix, $extension = '' ) {
30 $base = wfTempDir() . '/' . $prefix . dechex( mt_rand( 0, 99999999 ) );
31 $ext = ( $extension != '' ) ? ".{$extension}" : "";
32 for ( $attempt = 1; true; $attempt++ ) {
33 $path = "{$base}-{$attempt}{$ext}";
34 wfSuppressWarnings();
35 $newFileHandle = fopen( $path, 'x' );
36 wfRestoreWarnings();
37 if ( $newFileHandle ) {
38 fclose( $newFileHandle );
39 break; // got it
40 }
41 if ( $attempt >= 15 ) {
42 return null; // give up
43 }
44 }
45 $tmpFile = new self( $path );
46 if ( php_sapi_name() != 'cli' ) {
47 self::$instances[] = $tmpFile; // defer purge till shutdown
48 }
49 return $tmpFile;
50 }
51
52 /**
53 * Purge this file off the file system
54 *
55 * @return bool Success
56 */
57 public function purge() {
58 $this->canDelete = false; // done
59 wfSuppressWarnings();
60 $ok = unlink( $this->path );
61 wfRestoreWarnings();
62 return $ok;
63 }
64
65 /**
66 * Clean up the temporary file only after an object goes out of scope
67 *
68 * @param $object Object
69 * @return void
70 */
71 public function bind( $object ) {
72 if ( is_object( $object ) ) {
73 $object->tempFSFileReferences[] = $this;
74 }
75 }
76
77 /**
78 * Set flag to not clean up after the temporary file
79 *
80 * @return void
81 */
82 public function preserve() {
83 $this->canDelete = false;
84 }
85
86 /**
87 * Cleans up after the temporary file by deleting it
88 */
89 function __destruct() {
90 if ( $this->canDelete ) {
91 wfSuppressWarnings();
92 unlink( $this->path );
93 wfRestoreWarnings();
94 }
95 }
96 }