Index: trunk/extensions/Translate/Translate.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
13 | 13 | */ |
14 | 14 | |
15 | | -define( 'TRANSLATE_VERSION', '8.15' ); |
| 15 | +define( 'TRANSLATE_VERSION', '8.16' ); |
16 | 16 | |
17 | 17 | $wgExtensionCredits['specialpage'][] = array( |
18 | 18 | 'name' => 'Translate', |
— | — | @@ -28,6 +28,8 @@ |
29 | 29 | |
30 | 30 | $wgAutoloadClasses['TranslateUtils'] = $dir . 'TranslateUtils.php'; |
31 | 31 | $wgAutoloadClasses['HTMLSelector'] = $dir . 'TranslateUtils.php'; |
| 32 | +$wgAutoloadClasses['ResourceLoader'] = $dir . 'utils/ResourceLoader.php'; |
| 33 | +$wgAutoloadClasses['StringMatcher'] = $dir . 'utils/StringMatcher.php'; |
32 | 34 | |
33 | 35 | $wgAutoloadClasses['MessageChecks'] = $dir . 'MessageChecks.php'; |
34 | 36 | $wgAutoloadClasses['MessageGroups'] = $dir . 'MessageGroups.php'; |
Index: trunk/extensions/Translate/README |
— | — | @@ -35,6 +35,7 @@ |
36 | 36 | == Chages in version 9 == |
37 | 37 | * Not released |
38 | 38 | * (bug 12955) Numbers should be localized in Translate extension |
| 39 | +* Support branches for core messages |
39 | 40 | |
40 | 41 | == Changes in version 8 == |
41 | 42 | * Released 2008-02-06 |
Index: trunk/extensions/Translate/utils/StringMatcher.php |
— | — | @@ -0,0 +1,110 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class StringMatcher { |
| 5 | + protected $sPrefix = ''; |
| 6 | + protected $aExact = array(); |
| 7 | + protected $aPrefix = array(); |
| 8 | + protected $aRegex = array(); |
| 9 | + |
| 10 | + public static function EmptyMatcher() { |
| 11 | + return new StringMatcher( '', array() ); |
| 12 | + } |
| 13 | + |
| 14 | + public function __construct( $prefix, Array $strings ) { |
| 15 | + $this->sPrefix = $prefix; |
| 16 | + $this->init( $strings ); |
| 17 | + } |
| 18 | + |
| 19 | + protected function init( Array $strings ) { |
| 20 | + foreach ( $strings as $string ) { |
| 21 | + $pos = strpos( $string, '*' ); |
| 22 | + if ( $pos === false ) { |
| 23 | + $this->aExact[] = $string; |
| 24 | + } elseif ( $pos +1 === strlen($string) ) { |
| 25 | + $prefix = substr( $string, 0, -1 ); |
| 26 | + $this->aPrefix[$prefix] = strlen($prefix); |
| 27 | + } else { |
| 28 | + $string = str_replace( '\\*', '.+', preg_quote( $string ) ); |
| 29 | + $this->aRegex[] = "/^$string$/"; |
| 30 | + } |
| 31 | + } |
| 32 | + } |
| 33 | + |
| 34 | + public function match( $string ) { |
| 35 | + if ( in_array($string, $this->aExact) ) return true; |
| 36 | + |
| 37 | + foreach ( $this->aPrefix as $prefix => $len ) { |
| 38 | + if ( strncmp( $string, $prefix, $len ) === 0 ) return true; |
| 39 | + } |
| 40 | + |
| 41 | + foreach ( $this->aRegex as $regex ) { |
| 42 | + if ( preg_match( $regex, $string ) ) return true; |
| 43 | + } |
| 44 | + |
| 45 | + return false; |
| 46 | + } |
| 47 | + |
| 48 | + public function mangle( $data ) { |
| 49 | + if ( !$this->sPrefix ) { return $data; } |
| 50 | + if ( is_array( $data ) ) { |
| 51 | + return $this->mangleArray( $data ); |
| 52 | + } elseif ( is_string( $data ) ) { |
| 53 | + return $this->mangleString( $data ); |
| 54 | + } elseif ( $data === null ) { |
| 55 | + return $data; |
| 56 | + } else { |
| 57 | + throw new MWException( __METHOD__ . ": Unsupported datatype" ); |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + public function unMangle( $data ) { |
| 62 | + if ( !$this->sPrefix ) { return $data; } |
| 63 | + if ( is_array( $data ) ) { |
| 64 | + return $this->mangleArray( $data, true); |
| 65 | + } elseif ( is_string( $data ) ) { |
| 66 | + return $this->mangleString( $data, true ); |
| 67 | + } elseif ( $data === null ) { |
| 68 | + return $data; |
| 69 | + } else { |
| 70 | + throw new MWException( __METHOD__ . ": Unsupported datatype" ); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + |
| 75 | + protected function mangleString( $string, $reverse = false ) { |
| 76 | + if ( $reverse ) { |
| 77 | + return $this->unMangleString( $string ); |
| 78 | + } elseif ( $this->match( $string ) ) { |
| 79 | + return $this->sPrefix . $string; |
| 80 | + } else { |
| 81 | + return $string; |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + protected function unMangleString( $string ) { |
| 86 | + if ( strncmp( $string, $this->sPrefix, strlen($this->sPrefix) ) === 0 ) { |
| 87 | + return substr( $string, strlen( $this->sPrefix ) ); |
| 88 | + } else { |
| 89 | + return $string; |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + protected function mangleArray( Array $array, $reverse = false ) { |
| 94 | + $temp = array(); |
| 95 | + |
| 96 | + if ( isset($array[0]) ) { |
| 97 | + foreach ( $array as $key => &$value ) { |
| 98 | + $value = $this->mangleString( $value, $reverse ); |
| 99 | + $temp[$key] = $value; // Assign a reference |
| 100 | + } |
| 101 | + } else { |
| 102 | + foreach ( $array as $key => &$value ) { |
| 103 | + $key = $this->mangleString( $key, $reverse ); |
| 104 | + $temp[$key] = $value; // Assign a reference |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + return $temp; |
| 109 | + } |
| 110 | + |
| 111 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/Translate/utils/StringMatcher.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 112 | + native |
Index: trunk/extensions/Translate/utils/ResourceLoader.php |
— | — | @@ -0,0 +1,14 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class ResourceLoader { |
| 5 | + |
| 6 | + public static function loadVariableFromPHPFile( $_filename, $_variable ) { |
| 7 | + if ( !file_exists( $_filename ) ) { |
| 8 | + return null; |
| 9 | + } else { |
| 10 | + require( $_filename ); |
| 11 | + return isset( $$_variable ) ? $$_variable : null; |
| 12 | + } |
| 13 | + } |
| 14 | + |
| 15 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/Translate/utils/ResourceLoader.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 16 | + native |
Index: trunk/extensions/Translate/MessageGroups.php |
— | — | @@ -32,6 +32,9 @@ |
33 | 33 | */ |
34 | 34 | protected $fileExporter = null; |
35 | 35 | |
| 36 | + /*******/ |
| 37 | + protected $mangler = null; |
| 38 | + |
36 | 39 | /** |
37 | 40 | * Returns a human readable name of this group. |
38 | 41 | */ |
— | — | @@ -149,6 +152,8 @@ |
150 | 153 | // We copy only relevant translations to this new array |
151 | 154 | $new = array(); |
152 | 155 | foreach( $messages as $key => $m ) { |
| 156 | + $key = $this->mangler->unMangle( $key ); |
| 157 | + |
153 | 158 | # CASE1: ignored |
154 | 159 | if ( $m->ignored ) continue; |
155 | 160 | |
— | — | @@ -185,6 +190,11 @@ |
186 | 191 | return implode( "\n", $s ); |
187 | 192 | } |
188 | 193 | |
| 194 | + |
| 195 | + public function __construct() { |
| 196 | + $this->mangler = StringMatcher::emptyMatcher(); |
| 197 | + } |
| 198 | + |
189 | 199 | } |
190 | 200 | |
191 | 201 | class CoreMessageGroup extends MessageGroup { |
— | — | @@ -197,6 +207,10 @@ |
198 | 208 | return "Messages$code.php"; |
199 | 209 | } |
200 | 210 | |
| 211 | + protected function getFileLocation( $code ) { |
| 212 | + return Language::getMessagesFileName( $code ); |
| 213 | + } |
| 214 | + |
201 | 215 | public function getMessage( $key, $code ) { |
202 | 216 | $messages = $this->loadMessages( $code ); |
203 | 217 | return isset( $messages[$key] ) ? $messages[$key] : null; |
— | — | @@ -208,7 +222,7 @@ |
209 | 223 | } |
210 | 224 | |
211 | 225 | public function exportToFile( MessageCollection $messages, $authors ) { |
212 | | - $filename = Language::getMessagesFileName( $messages->code ); |
| 226 | + $filename = $this->getFileLocation( $messages->code ); |
213 | 227 | |
214 | 228 | $messagesAsString = $this->export( $messages ); |
215 | 229 | $name = TranslateUtils::getLanguageName( $messages->code ); |
— | — | @@ -232,28 +246,24 @@ |
233 | 247 | } |
234 | 248 | |
235 | 249 | function getDefinitions() { |
236 | | - return Language::getMessagesFor( 'en' ); |
| 250 | + return $this->loadMessages( 'en' ); |
237 | 251 | } |
238 | 252 | |
239 | 253 | public function getBools() { |
240 | 254 | $l = new languages(); |
241 | 255 | return array( |
242 | | - 'optional' => $l->getOptionalMessages(), |
243 | | - 'ignored' => $l->getIgnoredMessages(), |
| 256 | + 'optional' => $this->mangler->mangle( $l->getOptionalMessages() ), |
| 257 | + 'ignored' => $this->mangler->mangle( $l->getIgnoredMessages() ), |
244 | 258 | ); |
245 | 259 | } |
246 | 260 | |
247 | | - private function loadMessages( $code ) { |
| 261 | + protected function loadMessages( $code ) { |
248 | 262 | if ( !isset($this->mcache[$code]) ) { |
249 | | - $file = Language::getMessagesFileName( $code ); |
250 | | - if ( !file_exists( $file ) ) { |
251 | | - $this->mcache[$code] = null; |
252 | | - } else { |
253 | | - require( $file ); |
254 | | - return $this->mcache[$code] = isset( $messages ) ? $messages : null; |
255 | | - } |
| 263 | + $file = $this->getFileLocation( $code ); |
| 264 | + $this->mcache[$code] = $this->mangler->mangle( |
| 265 | + ResourceLoader::loadVariableFromPHPFile( $file, 'messages' ) |
| 266 | + ); |
256 | 267 | } |
257 | | - |
258 | 268 | return $this->mcache[$code]; |
259 | 269 | } |
260 | 270 | |
— | — | @@ -268,9 +278,6 @@ |
269 | 279 | if ( isset($infile[$key]) ) { |
270 | 280 | $messages[$key]->infile = $infile[$key]; |
271 | 281 | } |
272 | | - if ( $infbfile && isset($infbfile[$key]) ) { |
273 | | - $messages[$key]->fallback = $infbfile[$key]; |
274 | | - } |
275 | 282 | } |
276 | 283 | } |
277 | 284 | |
— | — | @@ -305,6 +312,25 @@ |
306 | 313 | } |
307 | 314 | } |
308 | 315 | |
| 316 | +class BranchedCoreMessageGroup extends CoreMessageGroup { |
| 317 | + protected $label = 'MediaWiki messages ($1)'; |
| 318 | + protected $id = 'core-$1'; |
| 319 | + protected $fileExporter = 'CoreExporter'; |
| 320 | + protected $path = '__BUG__'; |
| 321 | + protected $meta = true; |
| 322 | + |
| 323 | + public function __construct( $path, $branch, StringMatcher $mangler ) { |
| 324 | + $this->path = $path; |
| 325 | + $this->label = str_replace( '$1', $branch, $this->label ); |
| 326 | + $this->id = Sanitizer::escapeId( str_replace( '$1', $branch, $this->id ) ); |
| 327 | + $this->mangler = $mangler; |
| 328 | + } |
| 329 | + |
| 330 | + protected function getFileLocation( $code ) { |
| 331 | + return $this->path . '/' . $this->getMessageFile( $code ); |
| 332 | + } |
| 333 | +} |
| 334 | + |
309 | 335 | abstract class ExtensionMessageGroup extends MessageGroup { |
310 | 336 | protected $fileExporter = 'StandardExtensionExporter'; |
311 | 337 | /** |
— | — | @@ -2236,6 +2262,7 @@ |
2237 | 2263 | private $fileDir = 'freecol/'; |
2238 | 2264 | |
2239 | 2265 | public function __construct() { |
| 2266 | + parent::__construct(); |
2240 | 2267 | global $wgTranslateExtensionDirectory; |
2241 | 2268 | $this->fileDir = $wgTranslateExtensionDirectory . 'freecol/'; |
2242 | 2269 | } |
— | — | @@ -2323,6 +2350,7 @@ |
2324 | 2351 | * @param $source Mediawiki message that contains list of message keys. |
2325 | 2352 | */ |
2326 | 2353 | public function __construct( $id, $source ) { |
| 2354 | + parent::__construct(); |
2327 | 2355 | $this->id = $id; |
2328 | 2356 | $this->source = $source; |
2329 | 2357 | } |