r72684 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72683‎ | r72684 | r72685 >
Date:21:34, 9 September 2010
Author:tparscal
Status:ok
Tags:
Comment:
Added 2 more options for mime-type detection. We now detect if the Fileinfo PECL extension is available and use it (PHP 5.3+ will have this more commonly than older versions), then try and use the now deprecated mime_content_type, and finally resort to inferring the mime-type from the file extension. Also, now if all else fails, we will gracefully degrade functionality by not embedding resources with undeterminable mime-types.
Modified paths:
  • /trunk/phase3/includes/libs/CSSMin.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/libs/CSSMin.php
@@ -24,9 +24,9 @@
2525 * @author Trevor Parscal
2626 */
2727 class CSSMin {
28 -
 28+
2929 /* Constants */
30 -
 30+
3131 /**
3232 * Maximum file size to still qualify for in-line embedding as a data-URI
3333 *
@@ -34,9 +34,23 @@
3535 * result in a 1/3 increase in size.
3636 */
3737 const EMBED_SIZE_LIMIT = 24576;
38 -
 38+
 39+ /* Protected Static Members */
 40+
 41+ /** @var array List of common image files extensions and mime-types */
 42+ protected static $mimeTypes = array(
 43+ 'gif' => 'image/gif',
 44+ 'jpe' => 'image/jpeg',
 45+ 'jpeg' => 'image/jpeg',
 46+ 'jpg' => 'image/jpeg',
 47+ 'png' => 'image/png',
 48+ 'tif' => 'image/tiff',
 49+ 'tiff' => 'image/tiff',
 50+ 'xbm' => 'image/x-xbitmap',
 51+ );
 52+
3953 /* Static Methods */
40 -
 54+
4155 /**
4256 * Gets a list of local file paths which are referenced in a CSS style sheet
4357 *
@@ -47,7 +61,6 @@
4862 public static function getLocalFileReferences( $source, $path = null ) {
4963 $pattern = '/url\([\'"]?(?<file>[^\?\)\:]*)\??[^\)]*[\'"]?\)/';
5064 $files = array();
51 -
5265 if ( preg_match_all( $pattern, $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER ) ) {
5366 foreach ( $matches as $match ) {
5467 $file = ( isset( $path ) ? rtrim( $path, '/' ) . '/' : '' ) . "{$match['file'][0]}";
@@ -58,10 +71,9 @@
5972 }
6073 }
6174 }
62 -
6375 return $files;
6476 }
65 -
 77+
6678 /**
6779 * Remaps CSS URL paths and automatically embeds data URIs for URL rules preceded by an /* @embed * / comment
6880 *
@@ -70,26 +82,36 @@
7183 * @return string Remapped CSS data
7284 */
7385 public static function remap( $source, $path, $embed = true ) {
74 -
7586 $pattern = '/((?<embed>\s*\/\*\s*\@embed\s*\*\/)(?<rule>[^\;\}]*))?url\([\'"]?(?<file>[^\?\)\:]*)\??[^\)]*[\'"]?\)(?<extra>[^;]*)[\;]?/';
7687 $offset = 0;
77 -
7888 while ( preg_match( $pattern, $source, $match, PREG_OFFSET_CAPTURE, $offset ) ) {
7989 // Shortcuts
8090 $embed = $match['embed'][0];
8191 $rule = $match['rule'][0];
8292 $extra = $match['extra'][0];
8393 $file = "{$path}/{$match['file'][0]}";
84 -
8594 // Only proceed if we can access the file
8695 if ( file_exists( $file ) ) {
8796 // Add version parameter as a time-stamp in ISO 8601 format, using Z for the timezone, meaning GMT
8897 $url = "{$file}?" . gmdate( 'Y-m-d\TH:i:s\Z', round( filemtime( $file ), -2 ) );
89 -
 98+ // If we the mime-type can't be determined, no embedding will take place
 99+ $type = false;
 100+ // Try a couple of different ways to get the mime-type of a file, in order of preference
 101+ if ( function_exists( 'finfo_file' ) && function_exists( 'finfo_open' ) ) {
 102+ // As of PHP 5.3, this is how you get the mime-type of a file; it uses the Fileinfo PECL extension
 103+ $type = finfo_file( finfo_open( FILEINFO_MIME_TYPE ), $file );
 104+ } else if ( function_exists( 'mime_content_type' ) ) {
 105+ // Before this was deprecated in PHP 5.3, this used to be how you get the mime-type of a file
 106+ $type = mime_content_type( $file );
 107+ } else {
 108+ // Worst-case scenario has happend, use the file extension to infer the mime-type
 109+ $ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
 110+ if ( isset( self::$mimeTypes[$ext] ) ) {
 111+ $type = self::$mimeTypes[$ext];
 112+ }
 113+ }
90114 // Detect when URLs were preceeded with embed tags, and also verify file size is below the limit
91 - if ( $embed && $match['embed'][1] > 0 && filesize( $file ) < self::EMBED_SIZE_LIMIT ) {
92 - // If we ever get to PHP 5.3, we should use the Fileinfo extension instead of mime_content_type
93 - $type = mime_content_type( $file );
 115+ if ( $embed && $type && $match['embed'][1] > 0 && filesize( $file ) < self::EMBED_SIZE_LIMIT ) {
94116 // Strip off any trailing = symbols (makes browsers freak out)
95117 $data = base64_encode( file_get_contents( $file ) );
96118 // Build 2 CSS properties; one which uses a base64 encoded data URI in place of the @embed
@@ -110,10 +132,9 @@
111133 // Move the offset to the end of the match, leaving it alone
112134 $offset = $match[0][1] + strlen( $match[0][0] );
113135 }
114 -
115136 return $source;
116137 }
117 -
 138+
118139 /**
119140 * Removes whitespace from CSS data
120141 *

Status & tagging log