MediaWikiExtensionFFS.php
Go to the documentation of this file.00001 <?php
00017 class MediaWikiExtensionFFS extends SimpleFFS {
00018 public function supportsFuzzy() {
00019 return 'write';
00020 }
00021
00022 public function getFileExtensions() {
00023 return array( '.i18n.php' );
00024 }
00025
00031 protected static $cache = array();
00032
00039 protected function splitSections( $data, $filename = 'unknown' ) {
00040 $data = SimpleFFS::fixNewLines( $data );
00041
00042 $splitter = '$messages = array();';
00043
00044 $pos = strpos( $data, $splitter );
00045 if ( $pos === false ) {
00046 throw new MWException( "MWEFFS1: File $filename: splitter not found" );
00047 }
00048
00049 $offset = $pos + strlen( $splitter );
00050 $header = substr( $data, 0, $offset );
00051
00052 $pattern = '(?: /\*\* .*? \*/ \n )? (?: \\$.*? \n\);(?:\n\n|\s+\z) )';
00053 $regexp = "~$pattern~xsu";
00054 $matches = array();
00055 preg_match_all( $regexp, $data, $matches, PREG_SET_ORDER, $offset );
00056
00057 $sections = array();
00058 $sections[] = $header;
00059
00060 foreach ( $matches as $data ) {
00061 $pattern = "\\\$messages\['([a-z-]+)'\]";
00062 $regexp = "~$pattern~su";
00063 $matches = array();
00064 if ( !preg_match( $regexp, $data[0], $matches ) ) {
00065 throw new MWException( "MWEFFS2: File $filename: malformed section: {$data[0]}" );
00066 }
00067 $code = $matches[1];
00068
00069 $sections[$code] = rtrim( $data[0] );
00070 }
00071
00072 return $sections;
00073 }
00074
00075 public function read( $code ) {
00076 $filename = $this->group->getSourceFilePath( $code );
00077 if ( !file_exists( $filename ) ) {
00078 return false;
00079 }
00080
00081 if ( isset( self::$cache[$filename]['parsed'][$code] ) ) {
00082 return self::$cache[$filename]['parsed'][$code];
00083 }
00084
00085 if ( !isset( self::$cache[$filename] ) ) {
00086
00087 self::$cache = array();
00088
00089 $contents = file_get_contents( $filename );
00090 self::$cache[$filename]['sections'] =
00091 $this->splitSections( $contents, $filename );
00092 }
00093
00094
00095 $cache = &self::$cache[$filename];
00096
00097 $value = false;
00098 if ( isset( $cache['sections'][$code] ) ) {
00099 $value = $this->readFromVariable( $cache['sections'][$code] );
00100 }
00101
00102 $cache['parsed'][$code] = $value;
00103
00104 return $value;
00105 }
00106
00107 public function readFromVariable( $data ) {
00108 $messages = array();
00109 eval( $data );
00110
00111 $c = count( $messages );
00112 if ( $c !== 1 ) {
00113 throw new MWException( "MWEFFS3: Expected 1, got $c: $data" );
00114 }
00115
00116 $messages = array_shift( $messages );
00117 $mangler = $this->group->getMangler();
00118 $messages = $mangler->mangle( $messages );
00119
00120 return array(
00121 'MESSAGES' => $messages,
00122 );
00123 }
00124
00129 protected function writeReal( MessageCollection $collection ) {
00130 $mangler = $this->group->getMangler();
00131 $code = $collection->getLanguage();
00132
00133 $block = $this->generateMessageBlock( $collection, $mangler );
00134 if ( $block === false ) {
00135 return '';
00136 }
00137
00138
00139
00140
00141 $this->read( 'mul' );
00142 $filename = $this->group->getSourceFilePath( $code );
00143 $cache = &self::$cache[$filename];
00144
00145
00146 if ( isset( $cache['sections'][$code] ) ) {
00147
00148 $fromFile = self::parseAuthorsFromString( $cache['sections'][$code] );
00149 $collection->addCollectionAuthors( $fromFile );
00150 }
00151
00152 $authors = $collection->getAuthors();
00153 $authors = $this->filterAuthors( $authors, $code );
00154
00155 $authorList = '';
00156 foreach ( $authors as $author ) {
00157 $authorList .= "\n * @author $author";
00158 }
00159
00160
00161 $name = TranslateUtils::getLanguageName( $code );
00162 $native = TranslateUtils::getLanguageName( $code, $code );
00163
00164 $section = <<<PHP
00167 \$messages['$code'] = array($block);
00168 PHP;
00169
00170
00171
00172 $cache['sections'][$code] = $section;
00173
00174
00175 $sections = $cache['sections'];
00176 $priority = array();
00177
00178 global $wgTranslateDocumentationLanguageCode;
00179 $codes = array(
00180 0,
00181 $this->group->getSourceLanguage(),
00182 $wgTranslateDocumentationLanguageCode,
00183 );
00184 foreach ( $codes as $pcode ) {
00185 if ( isset( $sections[$pcode] ) ) {
00186 $priority[] = $sections[$pcode];
00187 unset( $sections[$pcode] );
00188 }
00189 }
00190
00191 ksort( $sections );
00192
00193 return implode( "\n\n", $priority ) . "\n\n" . implode( "\n\n", $sections ) . "\n";
00194 }
00195
00196 protected function generateMessageBlock( MessageCollection $collection, StringMatcher $mangler ) {
00197 $block = '';
00201 foreach ( $collection as $key => $m ) {
00202 $value = $m->translation();
00203 if ( $value === null ) {
00204 continue;
00205 }
00206
00207 $key = $mangler->unmangle( $key );
00208 $value = str_replace( TRANSLATE_FUZZY, '', $value );
00209 $fuzzy = $m->hasTag( 'fuzzy' ) ? ' # Fuzzy' : '';
00210
00211 $key = self::quote( $key );
00212 $value = self::quote( $value );
00213 $block .= "\t$key => $value,$fuzzy\n";
00214 }
00215
00216
00217 if ( $block === '' ) {
00218 return false;
00219 }
00220
00221 return "\n$block";
00222 }
00223
00229 protected static function parseAuthorsFromString( $string ) {
00230 preg_match_all( '/@author (.*)/', $string, $m );
00231
00232 return $m[1];
00233 }
00234
00242 protected static function quote( $value ) {
00243 # Check for the appropriate apostrophe and add the value
00244 # Quote \ here, because it needs always escaping
00245 $value = addcslashes( $value, '\\' );
00246
00247 # For readability
00248 $single = "'";
00249 $double = '"';
00250 $quote = $single;
00251
00252 # It is safe to use '-quoting, unless there is '-quote in the text
00253 if ( strpos( $value, $single ) !== false ) {
00254 # In case there are no variables that need to be escaped, just use "-quote
00255 if ( strpos( $value, $double ) === false && !preg_match( '/\$[^0-9]/', $value ) ) {
00256 $quote = $double;
00257 } else {
00258 # Something needs quoting, so pick the quote which causes less quoting
00259 $doubleEsc = substr_count( $value, $double ) + substr_count( $value, '$' );
00260 $singleEsc = substr_count( $value, $single );
00261
00262 if ( $doubleEsc < $singleEsc ) {
00263 $quote = $double;
00264 $extra = '$';
00265 } else {
00266 $extra = '';
00267 }
00268
00269 $value = addcslashes( $value, $quote . $extra );
00270 }
00271 }
00272
00273 return $quote . $value . $quote;
00274 }
00275 }