Simple.php

Go to the documentation of this file.
00001 <?php
00015 class SimpleFormatReader {
00016     const SEPARATOR = '----';
00017     const AUTHORPREFIX = 'Author: ';
00018 
00019     // One reader per file
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; // End of static header, if any
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     // Stored objects
00130     protected $group;
00131 
00132     // Stored data
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         /* Assuming there are only numerical keys, array_merge does
00149          * the right thing here, and wfMergeArray() does not, because
00150          * it overwrites instead of appending.
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; // shorthand
00194 
00195         // Open temporary stream
00196         $handle = fopen( 'php://temp', 'wt' );
00197 
00198         $this->addAuthors( $collection->getAuthors(), $code );
00199         $this->exportLanguage( $handle, $collection );
00200 
00201         // Fetch data
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     // Writing three
00227     protected function makeHeader( $handle, $code ) {
00228         fwrite( $handle, $this->formatAuthors( self::AUTHORPREFIX, $code ) );
00229         fwrite( $handle, self::SEPARATOR . "\n" );
00230     }
00231 
00232     /*
00233      * @todo Same as FFS::filterAuthors, except the $groupId param. Can probably be discarded.
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         // Check if there is any authors at all
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 }
Generated on Tue Oct 29 00:00:23 2013 for MediaWiki Translate Extension by  doxygen 1.6.3