(bug 26486) ResourceLoader modules with paths to nonexistent files cause PHP warnings...
authorRoan Kattouw <catrope@users.mediawiki.org>
Sat, 13 Aug 2011 21:25:02 +0000 (21:25 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Sat, 13 Aug 2011 21:25:02 +0000 (21:25 +0000)
RELEASE-NOTES-1.19
includes/resourceloader/ResourceLoaderFileModule.php

index 054d205..ee11da8 100644 (file)
@@ -48,6 +48,8 @@ production.
 * Do not convert text in the user interface language to another script.
 * (bug 26283) Previewing user JS/CSS pages doesn't load other user JS/CSS pages
 * (bug 11374) Improved diff readability for colorblind people.
+* (bug 26486) ResourceLoader modules with paths to nonexistent files cause PHP
+  warnings/notices to be thrown
 
 === API changes in 1.19 ===
 * (bug 19838) siprop=interwikimap can now use the interwiki cache.
index 8d50dca..ca215d5 100644 (file)
@@ -367,7 +367,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                }
 
                wfProfileIn( __METHOD__.'-filemtime' );
-               $filesMtime = max( array_map( 'filemtime', $files ) );
+               $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
                wfProfileOut( __METHOD__.'-filemtime' );
                $this->modifiedTime[$context->getHash()] = max(
                        $filesMtime,
@@ -493,10 +493,10 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                $js = '';
                foreach ( array_unique( $scripts ) as $fileName ) {
                        $localPath = $this->getLocalPath( $fileName );
-                       $contents = file_get_contents( $localPath );
-                       if ( $contents === false ) {
+                       if ( !file_exists( $localPath ) ) {
                                throw new MWException( __METHOD__.": script file not found: \"$localPath\"" );
                        }
+                       $contents = file_get_contents( $localPath );
                        if ( $wgResourceLoaderValidateStaticJS ) {
                                // Static files don't really need to be checked as often; unlike
                                // on-wiki module they shouldn't change unexpectedly without
@@ -542,17 +542,18 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * This method can be used as a callback for array_map()
         *
-        * @param $path String: File path of script file to read
+        * @param $path String: File path of style file to read
         * @param $flip bool
         *
         * @return String: CSS data in script file
+        * @throws MWException if the file doesn't exist
         */
        protected function readStyleFile( $path, $flip ) {
                $localPath = $this->getLocalPath( $path );
-               $style = file_get_contents( $localPath );
-               if ( $style === false ) {
+               if ( !file_exists( $localPath ) ) {
                        throw new MWException( __METHOD__.": style file not found: \"$localPath\"" );
                }
+               $style = file_get_contents( $localPath );
                if ( $flip ) {
                        $style = CSSJanus::transform( $style, true, false );
                }
@@ -571,6 +572,23 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $style, $dir, $remoteDir, true
                );
        }
+       
+       /**
+        * Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist
+        * but returns 1 instead.
+        * @param $filename string File name
+        * @return int UNIX timestamp, or 1 if the file doesn't exist
+        */
+       protected static function safeFilemtime( $filename ) {
+               if ( file_exists( $filename ) ) {
+                       return filemtime( $filename );
+               } else {
+                       // We only ever map this function on an array if we're gonna call max() after,
+                       // so return our standard minimum timestamps here. This is 1, not 0, because
+                       // wfTimestamp(0) == NOW
+                       return 1;
+               }
+       }
 
        /**
         * Get whether CSS for this module should be flipped