r107486 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r107485‎ | r107486 | r107487 >
Date:13:01, 28 December 2011
Author:nikerabbit
Status:ok
Tags:
Comment:
I18n #347: Refactor backend to support messages from multiple namespaces
Modified paths:
  • /trunk/extensions/Translate/Groups.php (modified) (history)
  • /trunk/extensions/Translate/MessageCollection.php (modified) (history)
  • /trunk/extensions/Translate/MessageGroups.php (modified) (history)
  • /trunk/extensions/Translate/TranslateEditAddons.php (modified) (history)
  • /trunk/extensions/Translate/TranslateTasks.php (modified) (history)
  • /trunk/extensions/Translate/api/ApiQueryMessageCollection.php (modified) (history)
  • /trunk/extensions/Translate/specials/SpecialManageGroups.php (modified) (history)
  • /trunk/extensions/Translate/utils/MessageTable.php (modified) (history)
  • /trunk/extensions/Translate/utils/MessageWebImporter.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/MessageCollection.php
@@ -34,6 +34,9 @@
3535 /// \arrayof{String,TMessage} %Message key => messages.
3636 protected $messages = null;
3737
 38+ /// Array
 39+ protected $reverseMap;
 40+
3841 // Database resources
3942
4043 /// \type{Database Result Resource} Stored message existence and fuzzy state.
@@ -127,6 +130,24 @@
128131 }
129132
130133 /**
 134+ * Returns list of titles of messages that are used in this collection after filtering.
 135+ * @return \list{Title}
 136+ * @since 2011-12-28
 137+ */
 138+ public function getTitles() {
 139+ return array_values( $this->keys );
 140+ }
 141+
 142+ /**
 143+ * Returns list of message keys that are used in this collection after filtering.
 144+ * @return \list{String}
 145+ * @since 2011-12-28
 146+ */
 147+ public function getMessageKeys() {
 148+ return array_keys( $this->keys );
 149+ }
 150+
 151+ /**
131152 * Returns stored message tags.
132153 * @param $type \string Tag type, usually optional or ignored.
133154 * @return \types{\list{String},\null} List of keys or null if no tags.
@@ -227,7 +248,7 @@
228249 */
229250 public function resetForNewLanguage( $code ) {
230251 $this->code = $code;
231 - $this->keys = $this->fixKeys( array_keys( $this->definitions->messages ) );
 252+ $this->keys = $this->fixKeys();
232253 $this->dbInfo = null;
233254 $this->dbData = null;
234255 $this->dbReviewData = null;
@@ -381,15 +402,9 @@
382403 $origKeys = $keys;
383404 }
384405
385 - $flipKeys = array_flip( $keys );
386 -
387406 foreach ( $this->dbInfo as $row ) {
388407 if ( $row->rt_type !== null ) {
389 - if ( !isset( $flipKeys[$row->page_title] ) ) {
390 - continue;
391 - }
392 -
393 - unset( $keys[$flipKeys[$row->page_title]] );
 408+ unset( $keys[$this->rowToKey( $row )] );
394409 }
395410 }
396411
@@ -414,15 +429,8 @@
415430 $origKeys = $keys;
416431 }
417432
418 - $flipKeys = array_flip( $keys );
419 -
420433 foreach ( $this->dbInfo as $row ) {
421 - // Remove messages which have a translation from keys
422 - if ( !isset( $flipKeys[$row->page_title] ) ) {
423 - continue;
424 - }
425 -
426 - unset( $keys[$flipKeys[$row->page_title]] );
 434+ unset( $keys[$this->rowToKey( $row )] );
427435 }
428436
429437 // Check also if there is something in the file that is not yet in the database
@@ -453,18 +461,16 @@
454462 $origKeys = $keys;
455463 }
456464
457 - $flipKeys = array_flip( $keys );
458 -
459465 foreach ( $this->dbData as $row ) {
460 - $realKey = $flipKeys[$row->page_title];
461 - if ( !isset( $this->infile[$realKey] ) ) {
 466+ $mkey = $this->rowToKey( $row );
 467+ if ( !isset( $this->infile[$mkey] ) ) {
462468 continue;
463469 }
464470
465471 $text = Revision::getRevisionText( $row );
466 - if ( $this->infile[$realKey] === $text ) {
 472+ if ( $this->infile[$mkey] === $text ) {
467473 // Remove unchanged messages from the list
468 - unset( $keys[$realKey] );
 474+ unset( $keys[$mkey] );
469475 }
470476 }
471477
@@ -488,15 +494,13 @@
489495 protected function filterReviewer( array $keys, /*bool*/ $condition, /*int*/ $user ) {
490496 $this->loadReviewInfo( $keys );
491497 $origKeys = $keys;
492 - $flipKeys = array_flip( $keys );
493498
494499 /* This removes messages from the list which have certain
495500 * reviewer (among others) */
496501 $user = intval( $user );
497502 foreach ( $this->dbReviewData as $row ) {
498503 if ( intval($row->trr_user) === $user ) {
499 - $realKey = $flipKeys[$row->page_title];
500 - unset( $keys[$realKey] );
 504+ unset( $keys[$this->rowToKey( $row )] );
501505 }
502506 }
503507
@@ -517,13 +521,11 @@
518522 protected function filterLastTranslator( array $keys, /*bool*/ $condition, /*int*/ $user ) {
519523 $this->loadData( $keys );
520524 $origKeys = $keys;
521 - $flipKeys = array_flip( $keys );
522525
523526 $user = intval( $user );
524527 foreach ( $this->dbData as $row ) {
525528 if ( intval($row->rev_user) === $user ) {
526 - $realKey = $flipKeys[$row->page_title];
527 - unset( $keys[$realKey] );
 529+ unset( $keys[$this->rowToKey( $row )] );
528530 }
529531 }
530532
@@ -539,18 +541,20 @@
540542 * @param $keys \list{String} List of keys in display format.
541543 * @return \arrayof{String,String} Array of keys in database format indexed by display format.
542544 */
543 - protected function fixKeys( array $keys ) {
 545+ protected function fixKeys() {
544546 $newkeys = array();
545 - $namespace = $this->definitions->namespace;
 547+ // array( namespace, pagename )
 548+ $pages = $this->definitions->getPages();
546549 $code = $this->code;
547550
548 - foreach ( $keys as $key ) {
549 - $title = Title::makeTitleSafe( $namespace, $key . '/' . $code );
 551+ foreach ( $pages as $key => $page ) {
 552+ list ( $namespace, $pagename ) = $page;
 553+ $title = Title::makeTitleSafe( $namespace, "$pagename/$code" );
550554 if ( !$title ) {
551 - wfWarn( "Invalid title $namespace:$key/$code" );
 555+ wfWarn( "Invalid title $namespace:$pagename/$code" );
552556 continue;
553557 }
554 - $newkeys[$key] = $title->getDBKey();
 558+ $newkeys[$key] = $title;
555559 }
556560 return $newkeys;
557561 }
@@ -572,14 +576,10 @@
573577 }
574578
575579 $dbr = wfGetDB( $dbtype );
576 -
577580 $tables = array( 'page', 'revtag' );
578 - $fields = array( 'page_title', 'rt_type' );
579 - $conds = array(
580 - 'page_namespace' => $this->definitions->namespace,
581 - 'page_title' => array_values( $keys ),
582 - );
583 - $joins = array( 'revtag' =>
 581+ $fields = array( 'page_namespace', 'page_title', 'rt_type' );
 582+ $conds = $this->getTitleConds( $dbr );
 583+ $joins = array( 'revtag' =>
584584 array(
585585 'LEFT JOIN',
586586 array( 'page_id=rt_page', 'page_latest=rt_revision', 'rt_type' => RevTag::getType( 'fuzzy' ) )
@@ -606,14 +606,10 @@
607607 }
608608
609609 $dbr = wfGetDB( $dbtype );
610 -
611610 $tables = array( 'page', 'translate_reviews' );
612 - $fields = array( 'page_title', 'trr_user' );
613 - $conds = array(
614 - 'page_namespace' => $this->definitions->namespace,
615 - 'page_title' => array_values( $keys ),
616 - );
617 - $joins = array( 'translate_reviews' =>
 611+ $fields = array( 'page_namespace', 'page_title', 'trr_user' );
 612+ $conds = $this->getTitleConds( $dbtype );
 613+ $joins = array( 'translate_reviews' =>
618614 array(
619615 'JOIN',
620616 array( 'page_id=trr_page', 'page_latest=trr_revision' )
@@ -642,13 +638,12 @@
643639 $dbr = wfGetDB( $dbtype );
644640
645641 $tables = array( 'page', 'revision', 'text' );
646 - $fields = array( 'page_title', 'page_latest', 'rev_user', 'rev_user_text', 'old_flags', 'old_text' );
 642+ $fields = array( 'page_namespace', 'page_title', 'page_latest', 'rev_user', 'rev_user_text', 'old_flags', 'old_text' );
647643 $conds = array(
648 - 'page_namespace' => $this->definitions->namespace,
649 - 'page_title' => array_values( $keys ),
650644 'page_latest = rev_id',
651645 'old_id = rev_text_id',
652646 );
 647+ $conds = array_merge( $conds, $this->getTitleConds( $dbr ) );
653648
654649 $res = $dbr->select( $tables, $fields, $conds, __METHOD__ );
655650
@@ -656,6 +651,63 @@
657652 }
658653
659654 /**
 655+ * Of the current set of keys, construct database query conditions.
 656+ * @since 2011-12-28
 657+ */
 658+ protected function getTitleConds( $db ) {
 659+ // Array of array( namespace, pagename )
 660+ $byNamespace = array();
 661+ foreach ( $this->getTitles() as $title ) {
 662+ $namespace = $title->getNamespace();
 663+ $pagename = $title->getDBKey();
 664+ $byNamespace[$namespace][] = $pagename;
 665+ }
 666+
 667+ $conds = array();
 668+ foreach ( $byNamespace as $namespaces => $pagenames ) {
 669+ $cond = array(
 670+ 'page_namespace' => $namespaces,
 671+ 'page_title' => $pagenames,
 672+ );
 673+
 674+ $conds[] = $db->makeList( $cond, LIST_AND );
 675+ }
 676+ return $conds;
 677+ }
 678+
 679+ /**
 680+ * Given two-dimensional map of namespace and pagenames, this uses
 681+ * database fields page_namespace and page_title as keys and returns
 682+ * the value for those indexes.
 683+ * @since 2011-12-23
 684+ */
 685+ protected function rowToKey( $row ) {
 686+ $map = $this->getReverseMap();
 687+ if ( isset( $map[$row->page_namespace][$row->page_title] ) ) {
 688+ return $map[$row->page_namespace][$row->page_title];
 689+ } else {
 690+ wfWarn( "Got unknown title from the database: {$row->page_namespace}:{$row->page_title}" );
 691+ return null;
 692+ }
 693+ }
 694+
 695+ /**
 696+ * Creates a two-dimensional map of namespace and pagenames.
 697+ * @since 2011-12-23
 698+ */
 699+ public function getReverseMap() {
 700+ if ( isset( $this->reverseMap ) ) {
 701+ return $this->reverseMap;
 702+ }
 703+
 704+ $map = array();
 705+ foreach ( $this->keys as $mkey => $title ) {
 706+ $map[$title->getNamespace()][$title->getDBKey()] = $mkey;
 707+ }
 708+ return $this->reverseMap = $map;
 709+ }
 710+
 711+ /**
660712 * Constructs all TMessages from the data accumulated so far.
661713 * Usually there is no need to call this method directly.
662714 */
@@ -665,35 +717,25 @@
666718 }
667719
668720 $messages = array();
669 -
670 - foreach ( array_keys( $this->keys ) as $key ) {
671 - $messages[$key] = new ThinMessage( $key, $this->definitions->messages[$key] );
 721+ $definitions = $this->definitions->getDefinitions();
 722+ foreach ( array_keys( $this->keys ) as $mkey ) {
 723+ $messages[$mkey] = new ThinMessage( $mkey, $definitions[$mkey] );
672724 }
673725
674 - $flipKeys = array_flip( $this->keys );
675 -
676726 // Copy rows if any.
677727 if ( $this->dbData !== null ) {
678728 foreach ( $this->dbData as $row ) {
679 - if ( !isset( $flipKeys[$row->page_title] ) ) {
680 - continue;
681 - }
682 -
683 - $key = $flipKeys[$row->page_title];
684 - $messages[$key]->setRow( $row );
685 - $messages[$key]->setProperty( 'revision', $row->page_latest );
 729+ $mkey = $this->rowToKey( $row );
 730+ $messages[$mkey]->setRow( $row );
 731+ $messages[$mkey]->setProperty( 'revision', $row->page_latest );
686732 }
687733 }
688734
689735 if ( $this->dbInfo !== null ) {
690736 $fuzzy = array();
691737 foreach ( $this->dbInfo as $row ) {
692 - if ( !isset( $flipKeys[$row->page_title] ) ) {
693 - continue;
694 - }
695 -
696738 if ( $row->rt_type !== null ) {
697 - $fuzzy[] = $flipKeys[$row->page_title];
 739+ $fuzzy[] = $this->rowToKey( $row );
698740 }
699741 }
700742
@@ -702,36 +744,33 @@
703745
704746 // Copy tags if any.
705747 foreach ( $this->tags as $type => $keys ) {
706 - foreach ( $keys as $key ) {
707 - if ( isset( $messages[$key] ) ) {
708 - $messages[$key]->setTag( $type );
 748+ foreach ( $keys as $mkey ) {
 749+ if ( isset( $messages[$mkey] ) ) {
 750+ $messages[$mkey]->setTag( $type );
709751 }
710752 }
711753 }
712754
713755 // Copy properties if any.
714756 foreach ( $this->properties as $type => $keys ) {
715 - foreach ( $keys as $key => $value ) {
716 - if ( isset( $messages[$key] ) ) {
717 - $messages[$key]->setProperty( $type, $value );
 757+ foreach ( $keys as $mkey => $value ) {
 758+ if ( isset( $messages[$mkey] ) ) {
 759+ $messages[$mkey]->setProperty( $type, $value );
718760 }
719761 }
720762 }
721763
722764 // Copy infile if any.
723 - foreach ( $this->infile as $key => $value ) {
724 - if ( isset( $messages[$key] ) ) {
725 - $messages[$key]->setInfile( $value );
 765+ foreach ( $this->infile as $mkey => $value ) {
 766+ if ( isset( $messages[$mkey] ) ) {
 767+ $messages[$mkey]->setInfile( $value );
726768 }
727769 }
728770
729771 if ( $this->dbReviewData !== null ) {
730772 foreach ( $this->dbReviewData as $row ) {
731 - if ( !isset( $flipKeys[$row->page_title] ) ) {
732 - continue;
733 - }
734 - $key = $flipKeys[$row->page_title];
735 - $messages[$key]->appendProperty( 'reviewers', $row->trr_user );
 773+ $mkey = $this->rowToKey( $row );
 774+ $messages[$mkey]->appendProperty( 'reviewers', $row->trr_user );
736775 }
737776 }
738777
@@ -820,14 +859,36 @@
821860
822861 /**
823862 * Wrapper for message definitions, just to beauty the code.
824 - * This is one reason why message collections and thus message groups are
825 - * restricted into single namespace.
 863+ *
 864+ * API totally changed in 2011-12-28
826865 */
827866 class MessageDefinitions {
828 - public $namespace;
829 - public $messages;
830 - public function __construct( $namespace, array $messages ) {
 867+ protected $namespace;
 868+ protected $messages;
 869+
 870+ public function __construct( array $messages, $namespace = false ) {
831871 $this->namespace = $namespace;
832872 $this->messages = $messages;
833873 }
 874+
 875+ public function getDefinitions() {
 876+ return $this->messages;
 877+ }
 878+
 879+ /**
 880+ * @return Array of Array( namespace, pagename )
 881+ */
 882+ public function getPages() {
 883+ $namespace = $this->namespace;
 884+ $pages = array();
 885+ foreach ( array_keys( $this->messages ) as $key ) {
 886+ if ( $namespace === false ) {
 887+ // pages are in format ex. "8:jan"
 888+ $pages[$key] = explode( $key, ':', 2 );
 889+ } else {
 890+ $pages[$key] = array( $namespace, $key );
 891+ }
 892+ }
 893+ return $pages;
 894+ }
834895 }
Index: trunk/extensions/Translate/MessageGroups.php
@@ -254,7 +254,7 @@
255255 $definitions = $this->getUniqueDefinitions();
256256 }
257257
258 - $defs = new MessageDefinitions( $this->namespaces[0], $definitions );
 258+ $defs = new MessageDefinitions( $definitions, $this->namespaces[0] );
259259 $collection = MessageCollection::newFromDefinitions( $defs, $code );
260260
261261 $bools = $this->getBools();
@@ -624,7 +624,7 @@
625625 $this->fill( $collection );
626626 $this->fillContents( $collection );
627627
628 - foreach ( array_keys( $collection->keys() ) as $key ) {
 628+ foreach ( $collection->getMessageKeys() as $key ) {
629629 if ( $collection[$key]->translation() === null ) {
630630 unset( $collection[$key] );
631631 }
@@ -635,7 +635,7 @@
636636
637637 function fill( MessageCollection $messages ) {
638638 $cache = $this->load( $messages->code );
639 - foreach ( array_keys( $messages->keys() ) as $key ) {
 639+ foreach ( $messages->getMessageKeys() as $key ) {
640640 if ( isset( $cache[$key] ) ) {
641641 if ( is_array( $cache[$key] ) ) {
642642 $messages[$key]->setInfile( implode( ',', $cache[$key] ) );
Index: trunk/extensions/Translate/TranslateEditAddons.php
@@ -40,7 +40,7 @@
4141 $code = $handle->getCode();
4242 $collection = $group->initCollection( $group->getSourceLanguage() );
4343 $collection->filter( 'optional' );
44 - $keys = array_keys( $collection->keys() );
 44+ $keys = $collection->getMessageKeys();
4545 $count = count( $keys );
4646
4747 $key = strtolower( strtr( $key, ' ', '_' ) );
Index: trunk/extensions/Translate/TranslateTasks.php
@@ -282,7 +282,7 @@
283283
284284 $start = time();
285285
286 - foreach ( $this->collection->keys() as $key => $_ ) {
 286+ foreach ( $this->collection->getMessageKeys() as $key ) {
287287 // Allow up to 10 seconds to search for suggestions.
288288 if ( time() - $start > 10 || TranslationHelpers::checkTranslationServiceFailure( 'tmserver' ) ) {
289289 unset( $this->collection[$key] );
Index: trunk/extensions/Translate/utils/MessageTable.php
@@ -61,12 +61,11 @@
6262 public function includeAssets() {
6363 global $wgOut;
6464 TranslationHelpers::addModules( $wgOut );
65 - $keys = array();
66 - $namespace = $this->group->getNamespace();
67 - foreach ( array_values( $this->collection->keys() ) as $name ) {
68 - $keys[] = Title::makeTitle( $namespace, $name )->getPrefixedDbKey();
 65+ $pages = array();
 66+ foreach ( $this->collection->getTitles() as $title ) {
 67+ $pages[] = $title->getPrefixedDBKey();
6968 }
70 - $vars = array( 'trlKeys' => $keys );
 69+ $vars = array( 'trlKeys' => $pages );
7170 $wgOut->addScript( Skin::makeVariablesScript( $vars ) );
7271 $wgOut->addModules( 'ext.translate.messagetable' );
7372 }
@@ -273,9 +272,8 @@
274273 protected function doLinkBatch() {
275274 $batch = new LinkBatch();
276275 $batch->setCaller( __METHOD__ );
277 - $ns = $this->group->getNamespace();
278 - foreach ( $this->collection->keys() as $key ) {
279 - $batch->add( $ns, $key );
 276+ foreach ( $this->collection->getTitles() as $title ) {
 277+ $batch->addObj( $title );
280278 }
281279 $batch->execute();
282280 }
Index: trunk/extensions/Translate/utils/MessageWebImporter.php
@@ -281,7 +281,7 @@
282282
283283 if ( !$process ) {
284284 $collection->filter( 'hastranslation', false );
285 - $keys = array_keys( $collection->keys() );
 285+ $keys = $collection->getMessageKeys();
286286
287287 $diff = array_diff( $keys, array_keys( $messages ) );
288288
Index: trunk/extensions/Translate/specials/SpecialManageGroups.php
@@ -349,7 +349,7 @@
350350
351351 if ( !$process ) {
352352 $collection->filter( 'hastranslation', false );
353 - $keys = array_keys( $collection->keys() );
 353+ $keys = $collection->getMessageKeys();
354354
355355 $diff = array_diff( $keys, array_keys( $messages ) );
356356
Index: trunk/extensions/Translate/Groups.php
@@ -254,7 +254,7 @@
255255 }
256256 }
257257
258 - $definitions = new MessageDefinitions( $namespace, $messages );
 258+ $definitions = new MessageDefinitions( $messages, $namespace );
259259 $collection = MessageCollection::newFromDefinitions( $definitions, $code );
260260 $this->setTags( $collection );
261261
@@ -666,7 +666,7 @@
667667 }
668668
669669 $namespace = $this->getNamespace();
670 - $definitions = new MessageDefinitions( $namespace, $messages );
 670+ $definitions = new MessageDefinitions( $messages, $namespace );
671671 $collection = MessageCollection::newFromDefinitions( $definitions, $code );
672672
673673 $this->setTags( $collection );
Index: trunk/extensions/Translate/api/ApiQueryMessageCollection.php
@@ -69,21 +69,21 @@
7070 $count = 0;
7171
7272 $props = array_flip( $params['prop'] );
73 - foreach ( $messages->keys() as $key => $dbkey ) {
 73+ foreach ( $messages->keys() as $mkey => $title ) {
7474 if ( ++$count > $params['limit'] ) {
7575 $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
7676 break;
7777 }
7878
7979 if ( is_null( $resultPageSet ) ) {
80 - $data = $this->extractMessageData( $result, $props, $messages[$key] );
 80+ $data = $this->extractMessageData( $result, $props, $messages[$mkey] );
8181 $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $data );
8282 if ( !$fit ) {
8383 $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
8484 break;
8585 }
8686 } else {
87 - $pages[] = Title::makeTitleSafe( $group->getNamespace(), $dbkey );
 87+ $pages[] = $title;
8888 }
8989 }
9090

Follow-up revisions

RevisionCommit summaryAuthorDate
r107492Wrong variable used, followup r107486nikerabbit14:00, 28 December 2011
r107494Followup r107486: explode params in wrong order, conds should be OR and since...nikerabbit14:29, 28 December 2011

Status & tagging log