Merge "Drop zh-tw message "saveprefs""
[lhc/web/wiklou.git] / includes / filerepo / file / File.php
index 6edd6fc..f40d216 100644 (file)
@@ -163,7 +163,8 @@ abstract class File implements IDBAccessObject {
         * @param FileRepo|bool $repo
         */
        function __construct( $title, $repo ) {
-               if ( $title !== false ) { // subclasses may not use MW titles
+               // Some subclasses do not use $title, but set name/title some other way
+               if ( $title !== false ) {
                        $title = self::normalizeTitle( $title, 'exception' );
                }
                $this->title = $title;
@@ -212,14 +213,15 @@ abstract class File implements IDBAccessObject {
        }
 
        /**
-        * Normalize a file extension to the common form, and ensure it's clean.
-        * Extensions with non-alphanumeric characters will be discarded.
+        * Normalize a file extension to the common form, making it lowercase and checking some synonyms,
+        * and ensure it's clean. Extensions with non-alphanumeric characters will be discarded.
+        * Keep in sync with mw.Title.normalizeExtension() in JS.
         *
-        * @param string $ext (without the .)
-        * @return string
+        * @param string $extension File extension (without the leading dot)
+        * @return string File extension in canonical form
         */
-       static function normalizeExtension( $ext ) {
-               $lower = strtolower( $ext );
+       static function normalizeExtension( $extension ) {
+               $lower = strtolower( $extension );
                $squish = array(
                        'htm' => 'html',
                        'jpeg' => 'jpg',
@@ -420,7 +422,13 @@ abstract class File implements IDBAccessObject {
        public function getLocalRefPath() {
                $this->assertRepoDefined();
                if ( !isset( $this->fsFile ) ) {
+                       $starttime = microtime( true );
                        $this->fsFile = $this->repo->getLocalReference( $this->getPath() );
+
+                       $statTiming = microtime( true ) - $starttime;
+                       RequestContext::getMain()->getStats()->timing(
+                               'media.thumbnail.generate.fetchoriginal', 1000 * $statTiming );
+
                        if ( !$this->fsFile ) {
                                $this->fsFile = false; // null => false; cache negative hits
                        }
@@ -1091,7 +1099,9 @@ abstract class File implements IDBAccessObject {
         * @return bool|MediaTransformOutput
         */
        public function generateAndSaveThumb( $tmpFile, $transformParams, $flags ) {
-               global $wgUseSquid, $wgIgnoreImageErrors;
+               global $wgIgnoreImageErrors;
+
+               $stats = RequestContext::getMain()->getStats();
 
                $handler = $this->getHandler();
 
@@ -1108,10 +1118,15 @@ abstract class File implements IDBAccessObject {
                        $this->generateBucketsIfNeeded( $normalisedParams, $flags );
                }
 
+               $starttime = microtime( true );
+
                // Actually render the thumbnail...
                $thumb = $handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
                $tmpFile->bind( $thumb ); // keep alive with $thumb
 
+               $statTiming = microtime( true ) - $starttime;
+               $stats->timing( 'media.thumbnail.generate.transform', 1000 * $statTiming );
+
                if ( !$thumb ) { // bad params?
                        $thumb = false;
                } elseif ( $thumb->isError() ) { // transform error
@@ -1122,6 +1137,9 @@ abstract class File implements IDBAccessObject {
                        }
                } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
                        // Copy the thumbnail from the file system into storage...
+
+                       $starttime = microtime( true );
+
                        $disposition = $this->getThumbDisposition( $thumbName );
                        $status = $this->repo->quickImport( $tmpThumbPath, $thumbPath, $disposition );
                        if ( $status->isOK() ) {
@@ -1129,19 +1147,14 @@ abstract class File implements IDBAccessObject {
                        } else {
                                $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $transformParams, $flags );
                        }
+
+                       $statTiming = microtime( true ) - $starttime;
+                       $stats->timing( 'media.thumbnail.generate.store', 1000 * $statTiming );
+
                        // Give extensions a chance to do something with this thumbnail...
                        Hooks::run( 'FileTransformed', array( $this, $thumb, $tmpThumbPath, $thumbPath ) );
                }
 
-               // Purge. Useful in the event of Core -> Squid connection failure or squid
-               // purge collisions from elsewhere during failure. Don't keep triggering for
-               // "thumbs" which have the main image URL though (bug 13776)
-               if ( $wgUseSquid ) {
-                       if ( !$thumb || $thumb->isError() || $thumb->getUrl() != $this->getURL() ) {
-                               SquidUpdate::purge( array( $thumbUrl ) );
-                       }
-               }
-
                return $thumb;
        }
 
@@ -1166,13 +1179,13 @@ abstract class File implements IDBAccessObject {
                        return false;
                }
 
+               $starttime = microtime( true );
+
                $params['physicalWidth'] = $bucket;
                $params['width'] = $bucket;
 
                $params = $this->getHandler()->sanitizeParamsForBucketing( $params );
 
-               $bucketName = $this->getBucketThumbName( $bucket );
-
                $tmpFile = $this->makeTransformTmpFile( $bucketPath );
 
                if ( !$tmpFile ) {
@@ -1181,6 +1194,8 @@ abstract class File implements IDBAccessObject {
 
                $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
 
+               $buckettime = microtime( true ) - $starttime;
+
                if ( !$thumb || $thumb->isError() ) {
                        return false;
                }
@@ -1190,6 +1205,9 @@ abstract class File implements IDBAccessObject {
                // this object exists
                $tmpFile->bind( $this );
 
+               RequestContext::getMain()->getStats()->timing(
+                       'media.thumbnail.generate.bucket', 1000 * $buckettime );
+
                return true;
        }
 
@@ -2230,4 +2248,13 @@ abstract class File implements IDBAccessObject {
                $handler = $this->getHandler();
                return $handler ? $handler->isExpensiveToThumbnail( $this ) : false;
        }
+
+       /**
+        * Whether the thumbnails created on the same server as this code is running.
+        * @since 1.25
+        * @return bool
+        */
+       public function isTransformedLocally() {
+               return true;
+       }
 }