00001 <?php 00012 class MessageWriter { 00013 static $optionalComment = 'only translate this message to other languages if you have to change it'; 00014 static $ignoredComment = "do not translate or duplicate this message to other languages"; 00015 00016 static $messageStructure; 00017 static $blockComments; 00018 static $ignoredMessages; 00019 static $optionalMessages; 00020 00029 public static function writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown ) { 00030 # Rewrite the messages array 00031 $messages = self::writeMessagesArray( $messages, $code == 'en', false, $removeUnknown ); 00032 $messagesText = $messages[0]; 00033 $sortedMessages = $messages[1]; 00034 00035 # Write to the file 00036 $filename = Language::getMessagesFileName( $code ); 00037 $contents = file_get_contents( $filename ); 00038 if( strpos( $contents, '$messages' ) !== false ) { 00039 $contents = explode( '$messages', $contents ); 00040 if( $messagesText == '$messages' . $contents[1] ) { 00041 echo "Generated messages for language $code. Same as the current file.\n"; 00042 } else { 00043 if( $write ) { 00044 $new = $contents[0]; 00045 $new .= $messagesText; 00046 file_put_contents( $filename, $new ); 00047 echo "Generated and wrote messages for language $code.\n"; 00048 } else { 00049 echo "Generated messages for language $code. Please run the script again (without the parameter \"dry-run\") to write the array to the file.\n"; 00050 } 00051 } 00052 if( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) { 00053 if ( $removeUnknown ) 00054 echo "\nThe following " . count( $sortedMessages['unknown'] ) . " unknown messages have been removed:\n"; 00055 else 00056 echo "\nThere are " . count( $sortedMessages['unknown'] ) . " unknown messages, please check them:\n"; 00057 foreach( $sortedMessages['unknown'] as $key => $value ) { 00058 echo "* " . $key . "\n"; 00059 } 00060 } 00061 } else { 00062 echo "Generated messages for language $code. There seem to be no messages array in the file.\n"; 00063 } 00064 } 00065 00074 public static function writeMessagesArray( $messages, $ignoredComments = false, $prefix = false, $removeUnknown = false ) { 00075 # Load messages 00076 $dir = $prefix ? $prefix : dirname( __FILE__ ); 00077 00078 require( $dir . '/messages.inc' ); 00079 self::$messageStructure = $wgMessageStructure; 00080 self::$blockComments = $wgBlockComments; 00081 00082 require( $dir . '/messageTypes.inc' ); 00083 self::$ignoredMessages = $wgIgnoredMessages; 00084 self::$optionalMessages = $wgOptionalMessages; 00085 00086 # Sort messages to blocks 00087 $sortedMessages['unknown'] = $messages; 00088 foreach( self::$messageStructure as $blockName => $block ) { 00089 foreach( $block as $key ) { 00090 if( array_key_exists( $key, $sortedMessages['unknown'] ) ) { 00091 $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key]; 00092 unset( $sortedMessages['unknown'][$key] ); 00093 } 00094 } 00095 } 00096 00097 # Write all the messages 00098 $messagesText = "\$messages = array( 00099 "; 00100 foreach( $sortedMessages as $block => $messages ) { 00101 # Skip if it's the block of unknown messages - handle that in the end of file 00102 if( $block == 'unknown' ) { 00103 continue; 00104 } 00105 00106 if( $ignoredComments ) { 00107 $ignored = self::$ignoredMessages; 00108 $optional = self::$optionalMessages; 00109 } else { 00110 $ignored = array(); 00111 $optional = array(); 00112 } 00113 $comments = self::makeComments( array_keys( $messages ), $ignored, $optional ); 00114 00115 # Write the block 00116 $messagesText .= self::writeMessagesBlock( self::$blockComments[$block], $messages, $comments ); 00117 } 00118 00119 # Write the unknown messages, alphabetically sorted. 00120 # Of course, we don't have any comments for them, because they are unknown. 00121 if ( !$removeUnknown ) { 00122 ksort( $sortedMessages['unknown'] ); 00123 $messagesText .= self::writeMessagesBlock( 'Unknown messages', $sortedMessages['unknown'] ); 00124 } 00125 $messagesText .= "); 00126 "; 00127 return array( $messagesText, $sortedMessages ); 00128 } 00129 00137 public static function makeComments( $messages, $ignored, $optional ) { 00138 # Comment collector 00139 $commentArray = array(); 00140 00141 # List of keys only 00142 foreach( $messages as $key ) { 00143 if( in_array( $key, $ignored ) ) { 00144 $commentArray[$key] = ' # ' . self::$ignoredComment; 00145 } elseif( in_array( $key, $optional ) ) { 00146 $commentArray[$key] = ' # ' . self::$optionalComment; 00147 } 00148 } 00149 00150 return $commentArray; 00151 } 00152 00163 public static function writeMessagesBlock( $blockComment, $messages, 00164 $messageComments = array(), $prefix = '' ) { 00165 00166 $blockText = ''; 00167 00168 # Skip the block if it includes no messages 00169 if( empty( $messages ) ) { 00170 return ''; 00171 } 00172 00173 # Format the block comment (if exists); check for multiple lines comments 00174 if( !empty( $blockComment ) ) { 00175 if( strpos( $blockComment, "\n" ) === false ) { 00176 $blockText .= "$prefix# $blockComment 00177 "; 00178 } else { 00179 $blockText .= "$prefix/* 00180 $blockComment 00181 */ 00182 "; 00183 } 00184 } 00185 00186 # Get max key length 00187 $maxKeyLength = max( array_map( 'strlen', array_keys( $messages ) ) ); 00188 00189 # Format the messages 00190 foreach( $messages as $key => $value ) { 00191 # Add the key name 00192 $blockText .= "$prefix'$key'"; 00193 00194 # Add the appropriate block whitespace 00195 $blockText .= str_repeat( ' ', $maxKeyLength - strlen( $key ) ); 00196 00197 # Refer to the value 00198 $blockText .= ' => '; 00199 00200 # Check for the appropriate apostrophe and add the value 00201 # Quote \ here, because it needs always escaping 00202 $value = addcslashes( $value, '\\' ); 00203 00204 # For readability 00205 $single = "'"; 00206 $double = '"'; 00207 00208 if( strpos( $value, $single ) === false ) { 00209 # Nothing ugly, just use ' 00210 $blockText .= $single.$value.$single; 00211 } elseif( strpos( $value, $double ) === false && !preg_match('/\$[a-zA-Z_\x7f-\xff]/', $value) ) { 00212 # No "-quotes, no variables that need quoting, use " 00213 $blockText .= $double.$value.$double; 00214 } else { 00215 # Something needs quoting, pick the quote which causes less quoting 00216 $quote = substr_count( $value, $double ) + substr_count( $value, '$' ) >= substr_count( $value, $single ) ? $single : $double; 00217 if( $quote === $double ) { 00218 $extra = '$'; 00219 } else { 00220 $extra = ''; 00221 } 00222 $blockText .= $quote . addcslashes( $value, $quote . $extra ) . $quote; 00223 } 00224 00225 # Comma 00226 $blockText .= ','; 00227 00228 # Add comments, if there is any 00229 if( array_key_exists( $key, $messageComments ) ) { 00230 $blockText .= $messageComments[$key]; 00231 } 00232 00233 # Newline 00234 $blockText .= " 00235 "; 00236 } 00237 00238 # Newline to end the block 00239 $blockText .= " 00240 "; 00241 00242 return $blockText; 00243 } 00244 }