MediaWiki  REL1_23
writeMessagesArray.inc
Go to the documentation of this file.
00001 <?php
00027 class MessageWriter {
00028     protected static $optionalComment =
00029         'only translate this message to other languages if you have to change it';
00030     protected static $ignoredComment = "do not translate or duplicate this message to other languages";
00031 
00032     protected static $messageStructure;
00033     protected static $blockComments;
00034     protected static $ignoredMessages;
00035     protected static $optionalMessages;
00036 
00048     public static function writeMessagesToFile( $messages, $code, $write, $listUnknown,
00049         $removeUnknown, $messagesFolder = false
00050     ) {
00051         # Rewrite the messages array
00052         $messages = self::writeMessagesArray( $messages, $code == 'en', false, $removeUnknown );
00053         $messagesText = $messages[0];
00054         $sortedMessages = $messages[1];
00055 
00056         # Write to the file
00057         if ( $messagesFolder ) {
00058             $filename = Language::getFileName( "$messagesFolder/Messages", $code );
00059         } else {
00060             $filename = Language::getMessagesFileName( $code );
00061         }
00062 
00063         if ( file_exists( $filename ) ) {
00064             $contents = file_get_contents( $filename );
00065         } else {
00066             $contents = '<?php
00067 $messages = array(
00068 );
00069 ';
00070         }
00071 
00072         if ( strpos( $contents, '$messages' ) !== false ) {
00073             $contents = explode( '$messages', $contents );
00074             if ( $messagesText == '$messages' . $contents[1] ) {
00075                 echo "Generated messages for language $code. Same as the current file.\n";
00076             } else {
00077                 if ( $write ) {
00078                     $new = $contents[0];
00079                     $new .= $messagesText;
00080                     file_put_contents( $filename, $new );
00081                     echo "Generated and wrote messages for language $code.\n";
00082                 } else {
00083                     echo "Generated messages for language $code.\n" .
00084                         "Please run the script again (without the parameter \"dry-run\") " .
00085                         "to write the array to the file.\n";
00086                 }
00087             }
00088             if ( $listUnknown && isset( $sortedMessages['unknown'] ) &&
00089                 !empty( $sortedMessages['unknown'] )
00090             ) {
00091                 if ( $removeUnknown ) {
00092                     echo "\nThe following " . count( $sortedMessages['unknown'] ) .
00093                         " unknown messages have been removed:\n";
00094                 } else {
00095                     echo "\nThere are " . count( $sortedMessages['unknown'] ) .
00096                         " unknown messages, please check them:\n";
00097                 }
00098                 foreach ( $sortedMessages['unknown'] as $key => $value ) {
00099                     echo "* " . $key . "\n";
00100                 }
00101             }
00102         } else {
00103             echo "Generated messages for language $code. There seem to be no messages array in the file.\n";
00104         }
00105     }
00106 
00119     public static function writeMessagesArray( $messages, $ignoredComments = false,
00120         $prefix = false, $removeUnknown = false
00121     ) {
00122         # Load messages
00123         $dir = $prefix ? $prefix : __DIR__;
00124 
00125         require $dir . '/messages.inc';
00126         self::$messageStructure = $wgMessageStructure;
00127         self::$blockComments = $wgBlockComments;
00128 
00129         require $dir . '/messageTypes.inc';
00130         self::$ignoredMessages = $wgIgnoredMessages;
00131         self::$optionalMessages = $wgOptionalMessages;
00132 
00133         # Sort messages to blocks
00134         $sortedMessages['unknown'] = $messages;
00135         foreach ( self::$messageStructure as $blockName => $block ) {
00139             foreach ( $block as $key ) {
00140                 if ( array_key_exists( $key, $sortedMessages['unknown'] ) ) {
00141                     $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key];
00142                     unset( $sortedMessages['unknown'][$key] );
00143                 }
00144             }
00145         }
00146 
00147         # Write all the messages
00148         $messagesText = "\$messages = array(
00149 ";
00150         foreach ( $sortedMessages as $block => $messages ) {
00151             # Skip if it's the block of unknown messages - handle that in the end of file
00152             if ( $block == 'unknown' ) {
00153                 continue;
00154             }
00155 
00156             if ( $ignoredComments ) {
00157                 $ignored = self::$ignoredMessages;
00158                 $optional = self::$optionalMessages;
00159             } else {
00160                 $ignored = array();
00161                 $optional = array();
00162             }
00163             $comments = self::makeComments( array_keys( $messages ), $ignored, $optional );
00164 
00165             # Write the block
00166             $messagesText .= self::writeMessagesBlock( self::$blockComments[$block], $messages, $comments );
00167         }
00168 
00169         # Write the unknown messages, alphabetically sorted.
00170         # Of course, we don't have any comments for them, because they are unknown.
00171         if ( !$removeUnknown ) {
00172             ksort( $sortedMessages['unknown'] );
00173             $messagesText .= self::writeMessagesBlock( 'Unknown messages', $sortedMessages['unknown'] );
00174         }
00175         $messagesText .= ");
00176 ";
00177 
00178         return array( $messagesText, $sortedMessages );
00179     }
00180 
00189     public static function makeComments( $messages, $ignored, $optional ) {
00190         # Comment collector
00191         $commentArray = array();
00192 
00193         # List of keys only
00194         foreach ( $messages as $key ) {
00195             if ( in_array( $key, $ignored ) ) {
00196                 $commentArray[$key] = ' # ' . self::$ignoredComment;
00197             } elseif ( in_array( $key, $optional ) ) {
00198                 $commentArray[$key] = ' # ' . self::$optionalComment;
00199             }
00200         }
00201 
00202         return $commentArray;
00203     }
00204 
00215     public static function writeMessagesBlock( $blockComment, $messages,
00216         $messageComments = array(), $prefix = '' ) {
00217 
00218         $blockText = '';
00219 
00220         # Skip the block if it includes no messages
00221         if ( empty( $messages ) ) {
00222             return '';
00223         }
00224 
00225         # Format the block comment (if exists); check for multiple lines comments
00226         if ( !empty( $blockComment ) ) {
00227             if ( strpos( $blockComment, "\n" ) === false ) {
00228                 $blockText .= "$prefix# $blockComment
00229 ";
00230             } else {
00231                 $blockText .= "$prefix/*
00232 $blockComment
00233 */
00234 ";
00235             }
00236         }
00237 
00238         # Get max key length
00239         $maxKeyLength = max( array_map( 'strlen', array_keys( $messages ) ) );
00240 
00241         # Format the messages
00242         foreach ( $messages as $key => $value ) {
00243             # Add the key name
00244             $blockText .= "$prefix'$key'";
00245 
00246             # Add the appropriate block whitespace
00247             $blockText .= str_repeat( ' ', $maxKeyLength - strlen( $key ) );
00248 
00249             # Refer to the value
00250             $blockText .= ' => ';
00251 
00252             # Check for the appropriate apostrophe and add the value
00253             # Quote \ here, because it needs always escaping
00254             $value = addcslashes( $value, '\\' );
00255 
00256             # For readability
00257             $single = "'";
00258             $double = '"';
00259 
00260             if ( strpos( $value, $single ) === false ) {
00261                 # Nothing ugly, just use '
00262                 $blockText .= $single . $value . $single;
00263             } elseif ( strpos( $value, $double ) === false &&
00264                 !preg_match( '/\$[a-zA-Z_\x7f-\xff]/', $value )
00265             ) {
00266                 # No "-quotes, no variables that need quoting, use "
00267                 $blockText .= $double . $value . $double;
00268             } else {
00269                 # Something needs quoting, pick the quote which causes less quoting
00270 
00271                 if ( substr_count( $value, $double ) + substr_count( $value, '$' ) >=
00272                     substr_count( $value, $single )
00273                 ) {
00274                     $quote = $single;
00275                 } else {
00276                     $quote = $double;
00277                 }
00278 
00279                 if ( $quote === $double ) {
00280                     $extra = '$';
00281                 } else {
00282                     $extra = '';
00283                 }
00284                 $blockText .= $quote . addcslashes( $value, $quote . $extra ) . $quote;
00285             }
00286 
00287             # Comma
00288             $blockText .= ',';
00289 
00290             # Add comments, if there is any
00291             if ( array_key_exists( $key, $messageComments ) ) {
00292                 $blockText .= $messageComments[$key];
00293             }
00294 
00295             # Newline
00296             $blockText .= "
00297 ";
00298         }
00299 
00300         # Newline to end the block
00301         $blockText .= "
00302 ";
00303 
00304         return $blockText;
00305     }
00306 }