00001 <?php
00015 class SimpleFormatReader {
00016 const SEPARATOR = '----';
00017 const AUTHORPREFIX = 'Author: ';
00018
00019
00020 protected $filename = false;
00021 protected $prefixLength;
00022
00023 public function __construct( $filename ) {
00024 if ( is_readable( $filename ) ) {
00025 $this->filename = $filename;
00026 }
00027 $this->prefixLength = strlen( self::AUTHORPREFIX );
00028 }
00029
00030 protected $authors = null;
00031 protected $staticHeader = '';
00032
00036 public function parseAuthors() {
00037 if ( $this->authors === null ) {
00038 $this->parseHeader();
00039 }
00040
00041 return $this->authors;
00042 }
00043
00049 public function parseStaticHeader() {
00050 if ( $this->staticHeader === '' ) {
00051 $this->parseHeader();
00052 }
00053
00054 return $this->staticHeader;
00055 }
00056
00061 protected function parseHeader() {
00062 $authors = array();
00063 $staticHeader = '';
00064
00065 if ( $this->filename !== false ) {
00066 $handle = fopen( $this->filename, 'rt' );
00067 $state = 0;
00068
00069 while ( !feof( $handle ) ) {
00070 $line = fgets( $handle );
00071
00072 if ( $state === 0 ) {
00073 if ( $line === "\n" ) {
00074 $state = 1;
00075 continue;
00076 }
00077
00078 $prefix = substr( $line, 0, $this->prefixLength );
00079
00080 if ( strcasecmp( $prefix, self::AUTHORPREFIX ) === 0 ) {
00081 $authors[] = substr( $line, $this->prefixLength );
00082 }
00083 } elseif ( $state === 1 ) {
00084 if ( $line === self::SEPARATOR ) {
00085 break;
00086 }
00087
00088 $staticHeader .= $line;
00089 }
00090 }
00091 fclose( $handle );
00092 }
00093
00094 $this->authors = $authors;
00095 $this->staticHeader = $staticHeader;
00096 }
00097
00098 protected $messagePattern = '/([^\0]+)\0([^\0]+)\0\n/U';
00099
00106 public function parseMessages( StringMangler $mangler ) {
00107 $data = file_get_contents( $this->filename );
00108 $messages = array();
00109 $matches = array();
00110
00111 preg_match_all( $this->messagePattern, $data, $matches, PREG_SET_ORDER );
00112 foreach ( $matches as $match ) {
00113 list( , $key, $value ) = $match;
00114 $messages[$key] = $value;
00115 }
00116
00117 return $messages;
00118 }
00119 }
00120
00125 class SimpleFormatWriter {
00126 const SEPARATOR = '----';
00127 const AUTHORPREFIX = 'Author: ';
00128
00129
00130 protected $group;
00131
00132
00133 protected $authors, $staticHeader;
00134
00135 public function __construct( MessageGroup $group ) {
00136 $this->group = $group;
00137 }
00138
00139 public function addAuthors( array $authors, $code ) {
00140 if ( $this->authors === null ) {
00141 $this->authors = array();
00142 }
00143
00144 if ( !isset( $this->authors[$code] ) ) {
00145 $this->authors[$code] = array();
00146 }
00147
00148
00149
00150
00151
00152 $this->authors[$code] = array_merge( $this->authors[$code], $authors );
00153 $this->authors[$code] = array_unique( $this->authors[$code] );
00154 }
00155
00156 public function load( $code ) {
00157 $reader = $this->group->getReader( $code );
00158
00159 if ( $reader ) {
00160 $this->addAuthors( $reader->parseAuthors(), $code );
00161 $this->staticHeader = $reader->parseStaticHeader();
00162 }
00163 }
00164
00165 public function fileExport( array $languages, $targetDirectory ) {
00166 foreach ( $languages as $code ) {
00167 $messages = $this->getMessagesForExport( $this->group, $code );
00168
00169 if ( !count( $messages ) ) {
00170 continue;
00171 }
00172
00173 $filename = $this->group->getMessageFile( $code );
00174 if ( !$filename ) {
00175 continue;
00176 }
00177 $target = $targetDirectory . '/' . $filename;
00178
00179 wfMkdirParents( dirname( $target ), null, __METHOD__ );
00180 $handle = fopen( $target, 'wt' );
00181
00182 if ( $handle === false ) {
00183 throw new MWException( 'Unable to open target for writing' );
00184 }
00185
00186 $this->exportLanguage( $handle, $messages );
00187
00188 fclose( $handle );
00189 }
00190 }
00191
00192 public function webExport( MessageCollection $collection ) {
00193 $code = $collection->code;
00194
00195
00196 $handle = fopen( 'php://temp', 'wt' );
00197
00198 $this->addAuthors( $collection->getAuthors(), $code );
00199 $this->exportLanguage( $handle, $collection );
00200
00201
00202 rewind( $handle );
00203 $data = stream_get_contents( $handle );
00204 fclose( $handle );
00205
00206 return $data;
00207 }
00208
00209 protected function getMessagesForExport( MessageGroup $group, $code ) {
00210 $collection = $this->group->initCollection( $code );
00211 $collection->filter( 'ignored' );
00212 $collection->filter( 'hastranslation', false );
00213 $collection->loadTranslations();
00214 $this->addAuthors( $collection->getAuthors(), $code );
00215
00216 return $collection;
00217 }
00218
00219 protected function exportLanguage( $target, MessageCollection $collection ) {
00220 $this->load( $collection->code );
00221 $this->makeHeader( $target, $collection->code );
00222 $this->exportStaticHeader( $target );
00223 $this->exportMessages( $target, $collection );
00224 }
00225
00226
00227 protected function makeHeader( $handle, $code ) {
00228 fwrite( $handle, $this->formatAuthors( self::AUTHORPREFIX, $code ) );
00229 fwrite( $handle, self::SEPARATOR . "\n" );
00230 }
00231
00232
00233
00234
00235 public function filterAuthors( array $authors, $code, $groupId ) {
00236 global $wgTranslateAuthorBlacklist;
00237
00238 foreach ( $authors as $i => $v ) {
00239 $hash = "$groupId;$code;$v";
00240
00241 $blacklisted = false;
00242 foreach ( $wgTranslateAuthorBlacklist as $rule ) {
00243 list( $type, $regex ) = $rule;
00244
00245 if ( preg_match( $regex, $hash ) ) {
00246 if ( $type === 'white' ) {
00247 $blacklisted = false;
00248 break;
00249 } else {
00250 $blacklisted = true;
00251 }
00252 }
00253 }
00254
00255 if ( $blacklisted ) {
00256 unset( $authors[$i] );
00257 }
00258 }
00259
00260 return $authors;
00261 }
00262
00263 protected function formatAuthors( $prefix, $code ) {
00264
00265 if ( empty( $this->authors[$code] ) ) {
00266 return '';
00267 }
00268
00269 $groupId = $this->group->getId();
00270 $authors = $this->authors[$code];
00271 $authors = $this->filterAuthors( $authors, $code, $groupId );
00272
00273 if ( empty( $authors ) ) {
00274 return '';
00275 }
00276
00277 sort( $authors );
00278
00279 $s = array();
00280 foreach ( $authors as $a ) {
00281 $s[] = $prefix . $a;
00282 }
00283
00284 return implode( "\n", $s ) . "\n";
00285 }
00286
00287 protected function exportStaticHeader( $target ) {
00288 if ( $this->staticHeader ) {
00289 fwrite( $target, $this->staticHeader . "\n" );
00290 }
00291 }
00292
00293 protected function exportMessages( $handle, MessageCollection $collection ) {
00294 $mangler = $this->group->getMangler();
00295
00296 foreach ( $collection as $item ) {
00297 $key = $mangler->unMangle( $item->key() );
00298 $value = str_replace( TRANSLATE_FUZZY, '', $item->translation() );
00299 fwrite( $handle, "$key\000$value\000\n" );
00300 }
00301 }
00302
00303 protected function getLanguageNames( $code ) {
00304 $name = TranslateUtils::getLanguageName( $code );
00305 $native = TranslateUtils::getLanguageName( $code, $code );
00306
00307 return array( $name, $native );
00308 }
00309 }