JavaFFS.php

Go to the documentation of this file.
00001 <?php
00002 
00012 class JavaFFS extends SimpleFFS {
00013     public function supportsFuzzy() {
00014         return 'write';
00015     }
00016 
00017     public function getFileExtensions() {
00018         return array( '.properties' );
00019     }
00020 
00021     protected $keySeparator = '=';
00022 
00026     public function __construct( FileBasedMessageGroup $group ) {
00027         parent::__construct( $group );
00028 
00029         if ( isset( $this->extra['keySeparator'] ) ) {
00030             $this->keySeparator = $this->extra['keySeparator'];
00031         }
00032     }
00033 
00034     // READ
00035 
00041     public function readFromVariable( $data ) {
00042         $data = self::fixNewLines( $data );
00043         $lines = array_map( 'ltrim', explode( "\n", $data ) );
00044         $authors = $messages = array();
00045         $linecontinuation = false;
00046 
00047         $key = '';
00048         $value = '';
00049         foreach ( $lines as $line ) {
00050             if ( $linecontinuation ) {
00051                 $linecontinuation = false;
00052                 $valuecont = $line;
00053                 $valuecont = str_replace( '\n', "\n", $valuecont );
00054                 $value .= $valuecont;
00055             } else {
00056                 if ( $line === '' ) {
00057                     continue;
00058                 }
00059 
00060                 if ( $line[0] === '#' || $line[0] === '!' ) {
00061                     $match = array();
00062                     $ok = preg_match( '/#\s*Author:\s*(.*)/', $line, $match );
00063 
00064                     if ( $ok ) {
00065                         $authors[] = $match[1];
00066                     }
00067 
00068                     continue;
00069                 }
00070 
00071                 if ( strpos( $line, $this->keySeparator ) === false ) {
00072                     throw new MWException( "Line without separator '{$this->keySeparator}': $line." );
00073                 }
00074 
00075                 list( $key, $value ) = self::readRow( $line, $this->keySeparator );
00076                 if ( $key === '' ) {
00077                     throw new MWException( "Empty key in line $line." );
00078                 }
00079             }
00080 
00081             // @todo This doesn't handle the pathological case of even number of trailing \
00082             if ( strlen( $value ) && $value[strlen( $value ) - 1] === "\\" ) {
00083                 $value = substr( $value, 0, strlen( $value ) - 1 );
00084                 $linecontinuation = true;
00085             } else {
00086                 $messages[$key] = ltrim( $value );
00087             }
00088         }
00089 
00090         $messages = $this->group->getMangler()->mangle( $messages );
00091 
00092         return array(
00093             'AUTHORS' => $authors,
00094             'MESSAGES' => $messages,
00095         );
00096     }
00097 
00098     // Write
00099 
00104     protected function writeReal( MessageCollection $collection ) {
00105         $header = $this->doHeader( $collection );
00106         $header .= $this->doAuthors( $collection );
00107         $header .= "\n";
00108 
00109         $output = '';
00110         $mangler = $this->group->getMangler();
00111 
00115         foreach ( $collection as $key => $m ) {
00116             $value = $m->translation();
00117             $value = str_replace( TRANSLATE_FUZZY, '', $value );
00118 
00119             if ( $value === '' ) {
00120                 continue;
00121             }
00122 
00123             // Just to give an overview of translation quality.
00124             if ( $m->hasTag( 'fuzzy' ) ) {
00125                 $output .= "# Fuzzy\n";
00126             }
00127 
00128             $key = $mangler->unmangle( $key );
00129             $output .= self::writeRow( $key, $this->keySeparator, $value );
00130         }
00131 
00132         if ( $output ) {
00133             return $header . $output;
00134         }
00135 
00136         return '';
00137     }
00138 
00147     public static function writeRow( $key, $sep, $value ) {
00148         /* Keys containing the separator need escaping. Also escape comment
00149          * characters, though strictly they would only need escaping when
00150          * they are the first character. Plus the escape character itself. */
00151         $key = addcslashes( $key, "#!$sep\\" );
00152         // Make sure we do not slip newlines trough... it would be fatal.
00153         $value = str_replace( "\n", '\\n', $value );
00154 
00155         return "$key$sep$value\n";
00156     }
00157 
00165     public static function readRow( $line, $sep ) {
00166         if ( strpos( $line, '\\' ) === false ) {
00167             /* Nothing appears to be escaped in this line.
00168              * Just read the key and the value. */
00169             list( $key, $value ) = explode( $sep, $line, 2 );
00170         } else {
00171             /* There might be escaped separators in the key.
00172              * Using slower method to find the separator. */
00173 
00174             /* Make the key default to empty instead of value, because
00175              * empty key causes error on callers, while empty value
00176              * wouldn't. */
00177             $key = '';
00178             $value = $line;
00179 
00180             /* Find the first unescaped separator. Example:
00181              * First line is the string being read, second line is the
00182              * value of $escaped after having read the above character.
00183              *
00184              * ki\ts\\s\=a = koira
00185              * 0010010010000
00186              *          ^ Not separator because $escaped was true
00187              *             ^ Split the string into key and value here
00188              */
00189 
00190             $len = strlen( $line );
00191             $escaped = false;
00192             for ( $i = 0; $i < $len; $i++ ) {
00193                 $char = $line[$i];
00194                 if ( $char === '\\' ) {
00195                     $escaped = !$escaped;
00196                 } elseif ( $escaped ) {
00197                     $escaped = false;
00198                 } elseif ( $char === $sep ) {
00199                     $key = substr( $line, 0, $i );
00200                     // Excluding the separator character from the value
00201                     $value = substr( $line, $i + 1 );
00202                     break;
00203                 }
00204             }
00205         }
00206 
00207         /* We usually don't want to expand things like \t in values since
00208          * translators cannot easily input those. But in keys we do.
00209          * \n is exception we do handle in values. */
00210         $key = trim( $key );
00211         $key = stripcslashes( $key );
00212         $value = ltrim( $value );
00213         $value = str_replace( '\n', "\n", $value );
00214 
00215         return array( $key, $value );
00216     }
00217 
00222     protected function doHeader( MessageCollection $collection ) {
00223         if ( isset( $this->extra['header'] ) ) {
00224             $output = $this->extra['header'];
00225         } else {
00226             global $wgSitename;
00227 
00228             $code = $collection->code;
00229             $name = TranslateUtils::getLanguageName( $code );
00230             $native = TranslateUtils::getLanguageName( $code, $code );
00231             $output = "# Messages for $name ($native)\n";
00232             $output .= "# Exported from $wgSitename\n";
00233         }
00234 
00235         return $output;
00236     }
00237 
00242     protected function doAuthors( MessageCollection $collection ) {
00243         $output = '';
00244         $authors = $collection->getAuthors();
00245         $authors = $this->filterAuthors( $authors, $collection->code );
00246 
00247         foreach ( $authors as $author ) {
00248             $output .= "# Author: $author\n";
00249         }
00250 
00251         return $output;
00252     }
00253 }
Generated on Tue Oct 29 00:00:23 2013 for MediaWiki Translate Extension by  doxygen 1.6.3