Merge "Allow to customise addHelpLink() target via system message"
[lhc/web/wiklou.git] / includes / filebackend / TempFSFile.php
index 611fab9..fa4eb5f 100644 (file)
@@ -34,6 +34,18 @@ class TempFSFile extends FSFile {
        /** @var array Active temp files to purge on shutdown */
        protected static $instances = array();
 
+       /** @var array Map of (path => 1) for paths to delete on shutdown */
+       protected static $pathsCollect = null;
+
+       public function __construct( $path ) {
+               parent::__construct( $path );
+
+               if ( self::$pathsCollect === null ) {
+                       self::$pathsCollect = array();
+                       register_shutdown_function( array( __CLASS__, 'purgeAllOnShutdown' ) );
+               }
+       }
+
        /**
         * Make a new temporary file on the file system.
         * Temporary files may be purged when the file object falls out of scope.
@@ -43,7 +55,6 @@ class TempFSFile extends FSFile {
         * @return TempFSFile|null
         */
        public static function factory( $prefix, $extension = '' ) {
-               wfProfileIn( __METHOD__ );
                $base = wfTempDir() . '/' . $prefix . wfRandomString( 12 );
                $ext = ( $extension != '' ) ? ".{$extension}" : "";
                for ( $attempt = 1; true; $attempt++ ) {
@@ -56,14 +67,12 @@ class TempFSFile extends FSFile {
                                break; // got it
                        }
                        if ( $attempt >= 5 ) {
-                               wfProfileOut( __METHOD__ );
 
                                return null; // give up
                        }
                }
                $tmpFile = new self( $path );
-               $tmpFile->canDelete = true; // safely instantiated
-               wfProfileOut( __METHOD__ );
+               $tmpFile->autocollect(); // safely instantiated
 
                return $tmpFile;
        }
@@ -79,13 +88,15 @@ class TempFSFile extends FSFile {
                $ok = unlink( $this->path );
                wfRestoreWarnings();
 
+               unset( self::$pathsCollect[$this->path] );
+
                return $ok;
        }
 
        /**
         * Clean up the temporary file only after an object goes out of scope
         *
-        * @param stdClass $object
+        * @param object $object
         * @return TempFSFile This object
         */
        public function bind( $object ) {
@@ -108,6 +119,8 @@ class TempFSFile extends FSFile {
        public function preserve() {
                $this->canDelete = false;
 
+               unset( self::$pathsCollect[$this->path] );
+
                return $this;
        }
 
@@ -119,17 +132,30 @@ class TempFSFile extends FSFile {
        public function autocollect() {
                $this->canDelete = true;
 
+               self::$pathsCollect[$this->path] = 1;
+
                return $this;
        }
 
+       /**
+        * Try to make sure that all files are purged on error
+        *
+        * This method should only be called internally
+        */
+       public static function purgeAllOnShutdown() {
+               foreach ( self::$pathsCollect as $path ) {
+                       wfSuppressWarnings();
+                       unlink( $path );
+                       wfRestoreWarnings();
+               }
+       }
+
        /**
         * Cleans up after the temporary file by deleting it
         */
        function __destruct() {
                if ( $this->canDelete ) {
-                       wfSuppressWarnings();
-                       unlink( $this->path );
-                       wfRestoreWarnings();
+                       $this->purge();
                }
        }
 }