Index: trunk/extensions/Translate/TranslateEditAddons.php |
— | — | @@ -259,7 +259,8 @@ |
260 | 260 | $message = new TMessage( $key, $en ); |
261 | 261 | // Take the contents from edit field as a translation |
262 | 262 | $message->database = $translation; |
263 | | - $checks = MessageChecks::doChecks( $message, $group->getType(), $code ); |
| 263 | + $checker = MessageChecks::getInstance(); |
| 264 | + $checks = $checker->doChecks( $message, $group->getType(), $code ); |
264 | 265 | if ( count($checks) ) { |
265 | 266 | $checkMessages = array(); |
266 | 267 | foreach ( $checks as $checkParams ) { |
Index: trunk/extensions/Translate/scripts/cli.inc |
— | — | @@ -14,26 +14,26 @@ |
15 | 15 | @include("$dir/../../CorePath.php"); // Allow override |
16 | 16 | require_once( "$IP/maintenance/commandLine.inc" ); |
17 | 17 | |
18 | | -function STDOUT( $str, $singeLineItem = null ) { |
| 18 | +function STDOUT( $str, $channel = null ) { |
19 | 19 | global $options; |
20 | 20 | if ( isset($options['quiet']) ) return; |
21 | 21 | |
22 | | - static $atStart = true; |
23 | | - static $lastSingle = false; |
| 22 | + static $lastChannel = null; |
| 23 | + static $lineStart = true; |
24 | 24 | |
25 | | - if ( !$atStart && $singeLineItem === null || !$lastSingle && !$atStart && $singeLineItem ) { |
26 | | - fwrite( STDOUT, "\n" ); |
| 25 | + if ( $channel !== null && ($lineStart || $channel === $lastChannel) ) { |
| 26 | + fwrite( STDOUT, $str ); |
| 27 | + } else { |
| 28 | + if ( !$lineStart ) fwrite( STDOUT, "\n" ); |
| 29 | + fwrite( STDOUT, $str ); |
27 | 30 | } |
28 | | - fwrite( STDOUT, $str ); |
29 | 31 | |
30 | | - if ( $singeLineItem !== true ) { |
| 32 | + $lineStart = false; |
| 33 | + if ( $channel === null ) { |
31 | 34 | fwrite( STDOUT, "\n" ); |
32 | | - $atStart = true; |
33 | | - $lastSingle = false; |
34 | | - } else { |
35 | | - $lastSingle = true; |
36 | | - $atStart = false; |
| 35 | + $lineStart = true; |
37 | 36 | } |
| 37 | + $lastChannel = $channel; |
38 | 38 | } |
39 | 39 | |
40 | 40 | function STDERR( $message ) { |
Index: trunk/extensions/Translate/scripts/createCheckIndex.php |
— | — | @@ -18,6 +18,9 @@ |
19 | 19 | if ( $wgTranslateDocumentationLanguageCode ) |
20 | 20 | unset( $codes[$wgTranslateDocumentationLanguageCode] ); |
21 | 21 | |
| 22 | +// Skip source |
| 23 | +unset($codes['en']); |
| 24 | + |
22 | 25 | $codes = array_keys( $codes ); |
23 | 26 | sort( $codes ); |
24 | 27 | |
— | — | @@ -27,21 +30,31 @@ |
28 | 31 | $reqGroups = false; |
29 | 32 | } |
30 | 33 | |
| 34 | +$verbose = isset($options['verbose']); |
| 35 | + |
31 | 36 | $groups = MessageGroups::singleton()->getGroups(); |
| 37 | +$checker = MessageChecks::getInstance(); |
32 | 38 | |
33 | 39 | foreach ( $groups as $g ) { |
34 | 40 | $id = $g->getId(); |
35 | 41 | |
36 | 42 | // Skip groups that are not requested |
37 | | - if ( $reqGroups && !in_array($id, $reqGroups) ) continue; |
| 43 | + if ( $reqGroups && !in_array($id, $reqGroups) ) { |
| 44 | + unset($g); |
| 45 | + continue; |
| 46 | + } |
38 | 47 | |
39 | 48 | $problematic = array(); |
40 | 49 | $type = $g->getType(); |
| 50 | + if ( !$checker->hasChecks($type) ) { |
| 51 | + unset($g); |
| 52 | + continue; |
| 53 | + } |
41 | 54 | |
42 | | - STDOUT( "Working with $id: ", true ); |
| 55 | + STDOUT( "Working with $id: ", $id ); |
43 | 56 | |
44 | 57 | foreach ( $codes as $code ) { |
45 | | - STDOUT( "$code ", true ); |
| 58 | + STDOUT( "$code ", $id ); |
46 | 59 | |
47 | 60 | // Initialise messages, using unique definitions if appropriate |
48 | 61 | $collection = $g->initCollection( $code, $g->isMeta() ); |
— | — | @@ -49,22 +62,27 @@ |
50 | 63 | $namespace = $g->namespaces[0]; |
51 | 64 | |
52 | 65 | foreach ( $collection->keys() as $key ) { |
53 | | - $prob = MessageChecks::doFastChecks( $collection[$key], $type, $code ); |
| 66 | + $prob = $checker->doFastChecks( $collection[$key], $type, $code ); |
54 | 67 | if ( $prob ) { |
55 | | - // Print it |
56 | | - $nsText = $wgContLang->getNsText( $namespace ); |
57 | | - STDOUT( "# [[$nsText:$key/$code]]" ); |
58 | 68 | |
| 69 | + if ( $verbose ) { |
| 70 | + // Print it |
| 71 | + $nsText = $wgContLang->getNsText( $namespace ); |
| 72 | + STDOUT( "# [[$nsText:$key/$code]]" ); |
| 73 | + } |
| 74 | + |
59 | 75 | // Add it to the array |
60 | | - $key = strtolower( "$namespace:$key" ); |
61 | | - $problematic[$code][] = $key; |
| 76 | + $problematic[$code][] = strtolower( "$namespace:$key" ); |
62 | 77 | } |
63 | 78 | } |
64 | | - |
65 | 79 | } |
66 | 80 | |
| 81 | + break; |
| 82 | + |
67 | 83 | // Store the results |
68 | 84 | $file = TRANSLATE_CHECKFILE . "-$id"; |
69 | 85 | wfMkdirParents( dirname($file) ); |
70 | 86 | file_put_contents( $file, serialize( $problematic ) ); |
71 | 87 | } |
| 88 | + |
| 89 | +unset( $checker ); |
\ No newline at end of file |
Index: trunk/extensions/Translate/MessageChecks.php |
— | — | @@ -10,26 +10,26 @@ |
11 | 11 | */ |
12 | 12 | class MessageChecks { |
13 | 13 | |
| 14 | + // Fastest first |
| 15 | + var $checksForType = array( |
| 16 | + 'mediawiki' => array( |
| 17 | + 'checkPlural', |
| 18 | + 'checkParameters', |
| 19 | + 'checkUnknownParameters', |
| 20 | + 'checkBalance', |
| 21 | + 'checkLinks', |
| 22 | + 'checkXHTML', |
| 23 | + ), |
| 24 | + 'freecol' => array( |
| 25 | + 'checkFreeColMissingVars', |
| 26 | + 'checkFreeColExtraVars', |
| 27 | + ), |
| 28 | + ); |
| 29 | + |
14 | 30 | private function __construct() { |
15 | 31 | $file = dirname(__FILE__) . '/check-blacklist.php'; |
16 | 32 | $this->blacklist = |
17 | 33 | ResourceLoader::loadVariableFromPHPFile( $file, 'checkBlacklist' ); |
18 | | - |
19 | | - // Fastest first |
20 | | - $this->checksForType = array( |
21 | | - 'mediawiki' => array( |
22 | | - array( $this, 'checkPlural' ), |
23 | | - array( $this, 'checkParameters' ), |
24 | | - array( $this, 'checkUnknownParameters' ), |
25 | | - array( $this, 'checkBalance' ), |
26 | | - array( $this, 'checkLinks' ), |
27 | | - array( $this, 'checkXHTML' ), |
28 | | - ), |
29 | | - 'freecol' => array( |
30 | | - array( $this, 'checkFreeColMissingVars' ), |
31 | | - array( $this, 'checkFreeColExtraVars' ), |
32 | | - ), |
33 | | - ); |
34 | 34 | } |
35 | 35 | |
36 | 36 | public static function getInstance() { |
— | — | @@ -40,9 +40,8 @@ |
41 | 41 | return $obj; |
42 | 42 | } |
43 | 43 | |
44 | | - public function getChecks( $type ) { |
45 | | - if ( !isset($this->checksForType[$type]) ) return array(); |
46 | | - return $this->checksForType[$type]; |
| 44 | + public function hasChecks( $type ) { |
| 45 | + return isset($this->checksForType[$type]); |
47 | 46 | } |
48 | 47 | |
49 | 48 | /** |
— | — | @@ -51,14 +50,13 @@ |
52 | 51 | * @param $message Instance of TMessage. |
53 | 52 | * @return Array of warning messages, html-format. |
54 | 53 | */ |
55 | | - public static function doChecks( TMessage $message, $type, $code ) { |
| 54 | + public function doChecks( TMessage $message, $type, $code ) { |
56 | 55 | if ( $message->translation === null) return false; |
57 | | - $obj = new MessageChecks; |
58 | 56 | $warnings = array(); |
59 | 57 | |
60 | | - foreach ( $obj->getChecks( $type ) as $check ) { |
| 58 | + foreach ( $this->checksForType[$type] as $check ) { |
61 | 59 | $warning = ''; |
62 | | - if ( call_user_func( $check, $message, $code, &$warning ) ) { |
| 60 | + if ( call_user_func( array($this, $check), $message, $code, &$warning ) ) { |
63 | 61 | $warnings[] = $warning; |
64 | 62 | } |
65 | 63 | } |
— | — | @@ -66,12 +64,11 @@ |
67 | 65 | return $warnings; |
68 | 66 | } |
69 | 67 | |
70 | | - public static function doFastChecks( TMessage $message, $type, $code ) { |
| 68 | + public function doFastChecks( TMessage $message, $type, $code ) { |
71 | 69 | if ( $message->translation === null) return false; |
72 | 70 | |
73 | | - $obj = new MessageChecks; |
74 | | - foreach ( $obj->getChecks( $type ) as $check ) { |
75 | | - if ( call_user_func( $check, $message, $code ) ) return true; |
| 71 | + foreach ( $this->checksForType[$type] as $check ) { |
| 72 | + if ( call_user_func( array($this, $check), $message, $code ) ) return true; |
76 | 73 | } |
77 | 74 | |
78 | 75 | return false; |
— | — | @@ -182,19 +179,21 @@ |
183 | 180 | * @return Array of problematic links. |
184 | 181 | */ |
185 | 182 | protected function checkLinks( TMessage $message, $code, &$desc = null ) { |
186 | | - $translation = $message->translation; |
187 | | - if ( strpos( $translation, '[[' ) === false ) return false; |
| 183 | + if ( strpos( $message->translation, '[[' ) === false ) return false; |
188 | 184 | |
189 | 185 | $matches = array(); |
190 | 186 | $links = array(); |
191 | 187 | $tc = Title::legalChars() . '#%{}'; |
192 | | - preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $translation, $matches); |
| 188 | + preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $message->translation, $matches); |
193 | 189 | for ($i = 0; $i < count($matches[0]); $i++ ) { |
194 | | - if ( preg_match( '/({{ns:)?special(}})?:.*/sDui', $matches[1][$i] ) ) continue; |
195 | | - if ( preg_match( '/{{mediawiki:.*}}/sDui', $matches[1][$i] ) ) continue; |
196 | | - if ( preg_match( '/user([ _]talk)?:.*/sDui', $matches[1][$i] ) ) continue; |
197 | | - if ( preg_match( '/:?\$[1-9]/sDu', $matches[1][$i] ) ) continue; |
| 190 | + //if ( preg_match( '/({{ns:)?special(}})?:.*/sDui', $matches[1][$i] ) ) continue; |
| 191 | + //if ( preg_match( '/{{mediawiki:.*}}/sDui', $matches[1][$i] ) ) continue; |
| 192 | + //if ( preg_match( '/user([ _]talk)?:.*/sDui', $matches[1][$i] ) ) continue; |
| 193 | + //if ( preg_match( '/:?\$[1-9]/sDu', $matches[1][$i] ) ) continue; |
198 | 194 | |
| 195 | + $backMatch = preg_quote( $matches[1][$i], '/' ); |
| 196 | + if ( preg_match( "/$backMatch/", $message->definition ) ) continue; |
| 197 | + |
199 | 198 | $links[] = "[[{$matches[1][$i]}|{$matches[2][$i]}]]"; |
200 | 199 | } |
201 | 200 | |
Index: trunk/extensions/Translate/TranslateUtils.php |
— | — | @@ -20,7 +20,14 @@ |
21 | 21 | */ |
22 | 22 | public static function title( $message, $code ) { |
23 | 23 | global $wgContLang; |
24 | | - return $wgContLang->ucfirst( $message . '/' . strtolower( $code ) ); |
| 24 | + |
| 25 | + // Cache some amount of titles for speed |
| 26 | + static $cache = array(); |
| 27 | + if ( count($cache)>500 ) $cache = array(); |
| 28 | + if ( !isset($cache[$message]) ) { |
| 29 | + $cache[$message] = $wgContLang->ucfirst($message); |
| 30 | + } |
| 31 | + return $cache[$message] . '/' . $code; |
25 | 32 | } |
26 | 33 | |
27 | 34 | /** |
Index: trunk/extensions/Translate/Message.php |
— | — | @@ -204,12 +204,12 @@ |
205 | 205 | /** |
206 | 206 | * String that uniquely identifies this message. |
207 | 207 | */ |
208 | | - private $key = null; |
| 208 | + public $key = null; |
209 | 209 | |
210 | 210 | /** |
211 | 211 | * The definition of this message - usually in English. |
212 | 212 | */ |
213 | | - private $definition = null; |
| 213 | + public $definition = null; |
214 | 214 | |
215 | 215 | // Following properties are lazy declared to save memory |
216 | 216 | |
— | — | @@ -235,8 +235,6 @@ |
236 | 236 | |
237 | 237 | // Values that can be accessed with $message->value syntax |
238 | 238 | protected static $callable = array( |
239 | | - // Obligatory basic values |
240 | | - 'key', 'definition', |
241 | 239 | // Basic values |
242 | 240 | 'infile', 'database', 'optional', 'pageExists', 'talkExists', |
243 | 241 | // Derived values |
— | — | @@ -279,14 +277,14 @@ |
280 | 278 | |
281 | 279 | /** Determines if this message has uncommitted changes. */ |
282 | 280 | public function changed() { |
283 | | - return $this->pageExists() && ( $this->infile() !== $this->database() ); |
| 281 | + return !!@$this->pageExists && ( @$this->infile !== @$this->database ); |
284 | 282 | } |
285 | 283 | |
286 | 284 | /** Determies if this message has a proper translation. */ |
287 | 285 | public function translated() { |
288 | | - if ( $this->fuzzy() ) return false; |
289 | | - $optionalSame = $this->optional() && ($this->translation() === $this->definition); |
290 | | - return ($this->translation() !== null) && !$optionalSame; |
| 286 | + if ( @$this->translation === null || $this->fuzzy() ) return false; |
| 287 | + $optionalSame = !!@$this->optional && (@$this->translation === @$this->definition); |
| 288 | + return !$optionalSame; |
291 | 289 | } |
292 | 290 | |
293 | 291 | /** |
— | — | @@ -296,7 +294,7 @@ |
297 | 295 | * @return Translated string or null if there isn't translation. |
298 | 296 | */ |
299 | 297 | public function translation() { |
300 | | - return ($this->database() !== null) ? $this->database() : $this->infile(); |
| 298 | + return (@$this->database !== null) ? @$this->database : @$this->infile; |
301 | 299 | } |
302 | 300 | |
303 | 301 | /** |
— | — | @@ -306,8 +304,8 @@ |
307 | 305 | * @return true or false |
308 | 306 | */ |
309 | 307 | public function fuzzy() { |
310 | | - if ( $this->translation() !== null ) { |
311 | | - return strpos($this->translation(), TRANSLATE_FUZZY) !== false; |
| 308 | + if ( @$this->translation !== null ) { |
| 309 | + return strpos($this->translation, TRANSLATE_FUZZY) !== false; |
312 | 310 | } else { |
313 | 311 | return false; |
314 | 312 | } |
— | — | @@ -342,11 +340,7 @@ |
343 | 341 | } |
344 | 342 | |
345 | 343 | public function __isset( $name ) { |
346 | | - if ( property_exists( $this, $name ) ) { |
347 | | - return $this->$name !== null; |
348 | | - } else { |
349 | | - return false; |
350 | | - } |
| 344 | + return @$this->$name !== null; |
351 | 345 | } |
352 | 346 | |
353 | 347 | } |