FFS.php
Go to the documentation of this file.00001 <?php
00019 interface FFS {
00020 public function __construct( FileBasedMessageGroup $group );
00021
00026 public function setWritePath( $target );
00027
00032 public function getWritePath();
00033
00041 public function read( $code );
00042
00049 public function readFromVariable( $data );
00050
00057 public function write( MessageCollection $collection );
00058
00066 public function writeIntoVariable( MessageCollection $collection );
00067
00076 public function supportsFuzzy();
00077
00084 public function getFileExtensions();
00085 }
00086
00093 class SimpleFFS implements FFS {
00094 public function supportsFuzzy() {
00095 return 'no';
00096 }
00097
00098 public function getFileExtensions() {
00099 return array();
00100 }
00101
00105 protected $group;
00106
00107 protected $writePath;
00108
00113 protected $extra;
00114
00115 const RECORD_SEPARATOR = "\0";
00116 const PART_SEPARATOR = "\0\0\0\0";
00117
00118 public function __construct( FileBasedMessageGroup $group ) {
00119 $this->setGroup( $group );
00120 $conf = $group->getConfiguration();
00121 $this->extra = $conf['FILES'];
00122 }
00123
00127 public function setGroup( FileBasedMessageGroup $group ) {
00128 $this->group = $group;
00129 }
00130
00134 public function getGroup() {
00135 return $this->group;
00136 }
00137
00141 public function setWritePath( $writePath ) {
00142 $this->writePath = $writePath;
00143 }
00144
00148 public function getWritePath() {
00149 return $this->writePath;
00150 }
00151
00162 public function exists( $code = false ) {
00163 if ( $code === false ) {
00164 $code = $this->group->getSourceLanguage();
00165 }
00166
00167 $filename = $this->group->getSourceFilePath( $code );
00168 if ( $filename === null ) {
00169 return false;
00170 }
00171
00172 if ( !file_exists( $filename ) ) {
00173 return false;
00174 }
00175
00176 return true;
00177 }
00178
00187 public function read( $code ) {
00188 if ( !$this->exists( $code ) ) {
00189 return false;
00190 }
00191
00192 $filename = $this->group->getSourceFilePath( $code );
00193 $input = file_get_contents( $filename );
00194 if ( $input === false ) {
00195 throw new MWException( "Unable to read file $filename." );
00196 }
00197
00198 return $this->readFromVariable( $input );
00199 }
00200
00209 public function readFromVariable( $data ) {
00210 $parts = explode( self::PART_SEPARATOR, $data );
00211
00212 if ( count( $parts ) !== 2 ) {
00213 throw new MWException( 'Wrong number of parts.' );
00214 }
00215
00216 list( $authorsPart, $messagesPart ) = $parts;
00217 $authors = explode( self::RECORD_SEPARATOR, $authorsPart );
00218 $messages = array();
00219
00220 foreach ( explode( self::RECORD_SEPARATOR, $messagesPart ) as $line ) {
00221 if ( $line === '' ) {
00222 continue;
00223 }
00224
00225 $lineParts = explode( '=', $line, 2 );
00226
00227 if ( count( $lineParts ) !== 2 ) {
00228 throw new MWException( "Wrong number of parts in line $line." );
00229 }
00230
00231 list( $key, $message ) = $lineParts;
00232 $key = trim( $key );
00233 $messages[$key] = $message;
00234 }
00235
00236 $messages = $this->group->getMangler()->mangle( $messages );
00237
00238 return array(
00239 'AUTHORS' => $authors,
00240 'MESSAGES' => $messages,
00241 );
00242 }
00243
00250 public function write( MessageCollection $collection ) {
00251 $writePath = $this->writePath;
00252
00253 if ( $writePath === null ) {
00254 throw new MWException( 'Write path is not set.' );
00255 }
00256
00257 if ( !file_exists( $writePath ) ) {
00258 throw new MWException( "Write path '$writePath' does not exist." );
00259 }
00260
00261 if ( !is_writable( $writePath ) ) {
00262 throw new MWException( "Write path '$writePath' is not writable." );
00263 }
00264
00265 $targetFile = $writePath . '/' . $this->group->getTargetFilename( $collection->code );
00266
00267 if ( file_exists( $targetFile ) ) {
00268 $this->tryReadSource( $targetFile, $collection );
00269 } else {
00270 $sourceFile = $this->group->getSourceFilePath( $collection->code );
00271 $this->tryReadSource( $sourceFile, $collection );
00272 }
00273
00274 $output = $this->writeReal( $collection );
00275 if ( $output ) {
00276 wfMkdirParents( dirname( $targetFile ), null, __METHOD__ );
00277 file_put_contents( $targetFile, $output );
00278 }
00279 }
00280
00287 public function writeIntoVariable( MessageCollection $collection ) {
00288 $sourceFile = $this->group->getSourceFilePath( $collection->code );
00289 $this->tryReadSource( $sourceFile, $collection );
00290
00291 return $this->writeReal( $collection );
00292 }
00293
00298 protected function writeReal( MessageCollection $collection ) {
00299 $output = '';
00300
00301 $authors = $collection->getAuthors();
00302 $authors = $this->filterAuthors( $authors, $collection->code );
00303
00304 $output .= implode( self::RECORD_SEPARATOR, $authors );
00305 $output .= self::PART_SEPARATOR;
00306
00307 $mangler = $this->group->getMangler();
00308
00309 foreach ( $collection as $key => $m ) {
00310 $key = $mangler->unmangle( $key );
00311 $trans = $m->translation();
00312 $output .= "$key=$trans" . self::RECORD_SEPARATOR;
00313 }
00314
00315 return $output;
00316 }
00317
00323 protected function tryReadSource( $filename, MessageCollection $collection ) {
00324 if ( $this->group instanceof SingleFileBasedMessageGroup ) {
00325 return;
00326 }
00327
00328 if ( get_class( $this->group->getFFS() ) !== get_class( $this ) ) {
00329 return;
00330 }
00331
00332 $sourceText = $this->tryReadFile( $filename );
00333
00334
00335
00336 if ( $sourceText !== false ) {
00337 $sourceData = $this->readFromVariable( $sourceText );
00338
00339 if ( isset( $sourceData['AUTHORS'] ) ) {
00340 $collection->addCollectionAuthors( $sourceData['AUTHORS'] );
00341 }
00342 }
00343 }
00344
00355 protected function tryReadFile( $filename ) {
00356 if ( !$filename ) {
00357 return false;
00358 }
00359
00360 if ( !file_exists( $filename ) ) {
00361 return false;
00362 }
00363
00364 if ( !is_readable( $filename ) ) {
00365 throw new MWException( "File $filename is not readable." );
00366 }
00367
00368 $data = file_get_contents( $filename );
00369 if ( $data === false ) {
00370 throw new MWException( "Unable to read file $filename." );
00371 }
00372
00373 return $data;
00374 }
00375
00383 protected function filterAuthors( array $authors, $code ) {
00384 global $wgTranslateAuthorBlacklist;
00385 $groupId = $this->group->getId();
00386
00387 foreach ( $authors as $i => $v ) {
00388 $hash = "$groupId;$code;$v";
00389
00390 $blacklisted = false;
00391 foreach ( $wgTranslateAuthorBlacklist as $rule ) {
00392 list( $type, $regex ) = $rule;
00393
00394 if ( preg_match( $regex, $hash ) ) {
00395 if ( $type === 'white' ) {
00396 $blacklisted = false;
00397 break;
00398 } else {
00399 $blacklisted = true;
00400 }
00401 }
00402 }
00403
00404 if ( $blacklisted ) {
00405 unset( $authors[$i] );
00406 }
00407 }
00408
00409 return $authors;
00410 }
00411
00419 public static function fixNewLines( $data ) {
00420 $data = str_replace( "\r\n", "\n", $data );
00421 $data = str_replace( "\r", "\n", $data );
00422
00423 return $data;
00424 }
00425 }