r89765 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89764‎ | r89765 | r89766 >
Date:10:21, 9 June 2011
Author:nikerabbit
Status:ok
Tags:
Comment:
Added language cloud to Special:SupportedLanguages and make it work without portal pages too
Modified paths:
  • /trunk/extensions/Translate/Translate.i18n.php (modified) (history)
  • /trunk/extensions/Translate/specials/SpecialSupportedLanguages.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/Translate.i18n.php
@@ -257,10 +257,6 @@
258258 'supportedlanguages-portallink' => '[$1] $2 - $3',
259259 'supportedlanguages-portallink-nocldr' => '[$1] $2',
260260 'supportedlanguages-translators' => '{{PLURAL:$2|Translator|Translators}}: $1',
261 - 'supportedlanguages-noportal-title' => 'No portal namespace defined',
262 - 'supportedlanguages-noportal' => 'The wiki administrator has not defined NS_PORTAL, so this page does not work.
263 -On this page a list of language portals will appear for all portals corresponding with a defined language code and a subpage called "translators".
264 -The subpage "translators" must contain the template [[:{{ns:template}}:User|User]], taking a user name as parameter.',
265261 'supportedlanguages-recenttranslations' => 'recent translations',
266262 'supportedlanguages-count' => '$1 {{PLURAL:$1|language|languages}} in total.',
267263 'supportedlanguages-activity' => '$1: $2 {{PLURAL:$2|edit|edits}} - last edit $3 {{PLURAL:$3|day|days}} ago',
Index: trunk/extensions/Translate/specials/SpecialSupportedLanguages.php
@@ -5,7 +5,7 @@
66 * @file
77 * @author Niklas Laxström
88 * @author Siebrand Mazeland
9 - * @copyright Copyright © 2010, Niklas Laxström, Siebrand Mazeland
 9+ * @copyright Copyright © 2011, Niklas Laxström, Siebrand Mazeland
1010 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
1111 */
1212
@@ -30,16 +30,10 @@
3131 public function execute( $par ) {
3232 global $wgLang, $wgOut, $wgRequest;
3333
34 - // Requires NS_PORTAL. If not present, display error text.
35 - if ( !defined( 'NS_PORTAL' ) ) {
36 - $wgOut->showErrorPage( 'supportedlanguages-noportal-title', 'supportedlanguages-noportal' );
37 - return;
38 - }
39 -
4034 $this->purge = $wgRequest->getVal( 'action' ) === 'purge';
4135
4236 $this->setHeaders();
43 - $wgOut->addModuleStyles( 'ext.translate.special.supportedlanguages' );
 37+ TranslateUtils::addModules( $wgOut, 'ext.translate.special.supportedlanguages' );
4438
4539 $cache = wfGetCache( CACHE_ANYTHING );
4640 $cachekey = wfMemcKey( 'translate-supportedlanguages', $wgLang->getCode() );
@@ -64,48 +58,22 @@
6559 $natives = Language::getLanguageNames( false );
6660 ksort( $natives );
6761
68 - $titles = array();
69 - foreach ( $natives as $code => $_ ) {
70 - $titles[] = Title::capitalize( $code, NS_PORTAL ) . '/translators';
71 - }
 62+ $this->outputLanguageCloud( $natives );
7263
73 - $dbr = wfGetDB( DB_SLAVE );
74 - $tables = array( 'page', 'revision', 'text' );
75 - $vars = array_merge( Revision::selectTextFields(), array( 'page_title', 'page_namespace' ), Revision::selectFields() );
76 - $conds = array(
77 - 'page_latest = rev_id',
78 - 'rev_text_id = old_id',
79 - 'page_namespace' => NS_PORTAL,
80 - 'page_title' => $titles,
81 - );
8264
83 - $res = $dbr->select( $tables, $vars, $conds, __METHOD__ );
84 -
85 - $users = array();
86 - $lb = new LinkBatch;
87 -
88 - foreach ( $res as $row ) {
89 - $rev = new Revision( $row );
90 - $text = $rev->getText();
91 - $code = strtolower( preg_replace( '!/translators$!', '', $row->page_title ) );
92 -
93 - preg_match_all( '!{{[Uu]ser\|([^}|]+)!', $text, $matches, PREG_SET_ORDER );
94 - foreach ( $matches as $match ) {
95 - $user = Title::capitalize( $match[1], NS_USER );
96 - $lb->add( NS_USER, $user );
97 - $lb->add( NS_USER_TALK, $user );
98 - if ( !isset( $users[$code] ) ) $users[$code] = array();
99 - $users[$code][] = strtr( $user, '_', ' ' );
100 - }
 65+ // Requires NS_PORTAL. If not present, display error text.
 66+ if ( !defined( 'NS_PORTAL' ) ) {
 67+ $users = $this->fetchTranslatorsAuto();
 68+ } else {
 69+ $users = $this->fetchTranslatorsPortal( $natives );
10170 }
10271
103 - $lb->execute();
 72+ $this->preQueryUsers( $users );
10473
10574 list( $editcounts, $lastedits ) = $this->getUserStats();
10675 global $wgUser;
10776
10877 $skin = $wgUser->getSkin();
109 - $portalBaseText = wfMsg( 'portal' );
11078
11179 // Information to be used inside the foreach loop.
11280 $linkInfo['rc']['title'] = SpecialPage::getTitleFor( 'Recentchanges' );
@@ -113,33 +81,29 @@
11482 $linkInfo['stats']['title'] = SpecialPage::getTitleFor( 'LanguageStats' );
11583 $linkInfo['stats']['msg'] = wfMsg( 'languagestats' );
11684
117 - foreach ( array_keys( $users ) as $code ) {
118 - $portalTitle = Title::makeTitleSafe( NS_PORTAL, $code );
119 - $portalText = $portalBaseText;
 85+ foreach ( array_keys( $natives ) as $code ) {
 86+ if ( !isset( $users[$code] ) ) continue;
12087
12188 // If CLDR is installed, add localised header and link title.
12289 if ( $cldrInstalled ) {
12390 $headerText = wfMsg( 'supportedlanguages-portallink', $code, $locals[$code], $natives[$code] );
124 - $portalText .= ' ' . $locals[$code];
12591 } else {
12692 // No CLDR, so a less localised header and link title.
12793 $headerText = wfMsg( 'supportedlanguages-portallink-nocldr', $code, $natives[$code] );
128 - $portalText .= ' ' . $natives[$code];
12994 }
13095
131 - $portalLink = $skin->link(
132 - $portalTitle,
133 - $headerText,
134 - array(
135 - 'id' => $code,
136 - 'title' => $portalText
137 - ),
138 - array(),
139 - array( 'known', 'noclasses' )
140 - );
 96+ $headerText = htmlspecialchars( $headerText );
14197
142 - $wgOut->addHTML( "<h2>" . $portalLink . "</h2>" );
 98+ $wgOut->addHtml( Html::openElement( 'h2', array( 'id' => $code ) ) );
 99+ if ( defined( 'NS_PORTAL' ) ) {
 100+ $portalTitle = Title::makeTitleSafe( NS_PORTAL, $code );
 101+ $wgOut->addHtml( $skin->linkKnown( $portalTitle, $headerText ) );
 102+ } else {
 103+ $wgOut->addHtml( $headerText );
 104+ }
143105
 106+ $wgOut->addHTML( "</h2>" );
 107+
144108 // Add useful links for language stats and recent changes for the language.
145109 $links = array();
146110 $links[] = $skin->link(
@@ -174,6 +138,131 @@
175139 $cache->set( $cachekey, $wgOut->getHTML(), 3600 );
176140 }
177141
 142+ protected function languageCloud() {
 143+ global $wgTranslateMessageNamespaces;
 144+
 145+ $cache = wfGetCache( CACHE_ANYTHING );
 146+ $cachekey = wfMemcKey( 'translate-supportedlanguages-language-cloud' );
 147+ $data = $cache->get( $cachekey );
 148+ if ( !$this->purge && is_array( $data ) ) {
 149+ return $data;
 150+ }
 151+
 152+ $dbr = wfGetDB( DB_SLAVE );
 153+ $tables = array( 'recentchanges' );
 154+ $fields = array( 'substring_index(rc_title, \'/\', -1) as lang', 'count(*) as count' );
 155+ $conds = array(
 156+ 'rc_title' . $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() ),
 157+ 'rc_namespace' => $wgTranslateMessageNamespaces,
 158+ 'rc_timestamp > ' . $dbr->timestamp( TS_DB, wfTimeStamp( TS_UNIX ) - 60*60*24*180 ),
 159+ );
 160+ $options = array( 'GROUP BY' => 'lang', 'HAVING' => 'count > 20' );
 161+
 162+ $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options );
 163+
 164+ $data = array();
 165+ foreach ( $res as $row ) {
 166+ $data[$row->lang] = $row->count;
 167+ }
 168+
 169+ $cache->set( $cachekey, $data, 3600 );
 170+ return $data;
 171+ }
 172+
 173+ protected function fetchTranslatorsAuto() {
 174+ global $wgTranslateMessageNamespaces;
 175+
 176+ $cache = wfGetCache( CACHE_ANYTHING );
 177+ $cachekey = wfMemcKey( 'translate-supportedlanguages-translator-list' );
 178+ $data = $cache->get( $cachekey );
 179+ if ( !$this->purge && is_array( $data ) ) {
 180+ return $data;
 181+ }
 182+
 183+ $dbr = wfGetDB( DB_SLAVE );
 184+ $tables = array( 'page', 'revision' );
 185+ $fields = array( 'rev_user_text', 'substring_index(page_title, \'/\', -1) as lang', 'count(page_id) as count' );
 186+ $conds = array(
 187+ 'page_title' . $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() ),
 188+ 'page_namespace' => $wgTranslateMessageNamespaces,
 189+ 'page_id=rev_page',
 190+ );
 191+ $options = array( 'GROUP BY' => 'rev_user_text, lang' );
 192+
 193+ $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options );
 194+
 195+ $data = array();
 196+ foreach ( $res as $row ) {
 197+ $data[$row->lang][$row->rev_user_text] = $row->count;
 198+ }
 199+
 200+ $cache->set( $cachekey, $data, 3600 );
 201+ return $data;
 202+ }
 203+
 204+ public function fetchTranslatorsPortal( $natives ) {
 205+ $titles = array();
 206+ foreach ( $natives as $code => $_ ) {
 207+ $titles[] = Title::capitalize( $code, NS_PORTAL ) . '/translators';
 208+ }
 209+
 210+ $dbr = wfGetDB( DB_SLAVE );
 211+ $tables = array( 'page', 'revision', 'text' );
 212+ $vars = array_merge( Revision::selectTextFields(), array( 'page_title', 'page_namespace' ), Revision::selectFields() );
 213+ $conds = array(
 214+ 'page_latest = rev_id',
 215+ 'rev_text_id = old_id',
 216+ 'page_namespace' => NS_PORTAL,
 217+ 'page_title' => $titles,
 218+ );
 219+
 220+ $res = $dbr->select( $tables, $vars, $conds, __METHOD__ );
 221+
 222+ $users = array();
 223+ $lb = new LinkBatch;
 224+
 225+ foreach ( $res as $row ) {
 226+ $rev = new Revision( $row );
 227+ $text = $rev->getText();
 228+ $code = strtolower( preg_replace( '!/translators$!', '', $row->page_title ) );
 229+
 230+ preg_match_all( '!{{[Uu]ser\|([^}|]+)!', $text, $matches, PREG_SET_ORDER );
 231+ foreach ( $matches as $match ) {
 232+ $user = Title::capitalize( $match[1], NS_USER );
 233+ $lb->add( NS_USER, $user );
 234+ $lb->add( NS_USER_TALK, $user );
 235+ if ( !isset( $users[$code] ) ) $users[$code] = array();
 236+ $users[$code][strtr( $user, '_', ' ' )] = -1;
 237+ }
 238+ }
 239+
 240+ $lb->execute();
 241+ return $users;
 242+ }
 243+
 244+
 245+ protected function outputLanguageCloud( $names ) {
 246+ global $wgOut;
 247+
 248+ $langs = $this->languageCloud();
 249+ $wgOut->addHtml( '<div class="tagcloud">' );
 250+ $langs = $this->shuffle_assoc( $langs );
 251+ foreach ( $langs as $k => $v ) {
 252+ $name = isset( $names[$k] ) ? $names[$k] : $k;
 253+ $size = round( log( $v ) * 20 ) + 10;
 254+
 255+ $params = array(
 256+ 'href' => "#$k",
 257+ 'class' => 'tag',
 258+ 'style' => "font-size:$size%",
 259+ );
 260+
 261+ $tag = Html::element( 'a', $params, $name );
 262+ $wgOut->addHtml( $tag ."\n" );
 263+ }
 264+ $wgOut->addHtml( '</div>' );
 265+ }
 266+
178267 protected function makeUserList( $users, $editcounts, $lastedits ) {
179268 global $wgOut, $wgLang, $wgUser;
180269 $skin = $wgUser->getSkin();
@@ -184,14 +273,17 @@
185274 // longer than this is just inactive
186275 $period = 180;
187276
188 - foreach ( $users as $index => $username ) {
 277+ $links = array();
 278+
 279+ foreach ( $users as $username => $count ) {
189280 $title = Title::makeTitleSafe( NS_USER, $username );
190281 $enc = htmlspecialchars( $username );
191282
192283 $attribs = array();
193284 $styles = array();
194285 if ( isset( $editcounts[$username] ) ) {
195 - $count = $editcounts[$username];
 286+ if ( $count === -1 ) $count = $editcounts[$username];
 287+
196288 $styles['font-size'] = round( log( $count, 10 ) * 30 ) + 70 . '%';
197289
198290 $last = wfTimestamp( TS_UNIX ) - $lastedits[$username];
@@ -208,14 +300,14 @@
209301 $stylestr = $this->formatStyle( $styles );
210302 if ( $stylestr ) $attribs['style'] = $stylestr;
211303
212 - $users[$index] = $skin->link( $title, $enc, $attribs );
 304+ $links[] = $skin->link( $title, $enc, $attribs );
213305 }
214306
215307 $wgOut->addHTML( "<p class='mw-translate-spsl-translators'>" . wfMsgExt(
216308 'supportedlanguages-translators',
217309 'parsemag',
218 - $wgLang->listToText( $users ),
219 - count( $users )
 310+ $wgLang->listToText( $links ),
 311+ count( $links )
220312 ) . "</p>\n" );
221313 }
222314
@@ -270,4 +362,29 @@
271363
272364 return $red . $green . $blue;
273365 }
 366+
 367+ function shuffle_assoc($list) {
 368+ if (!is_array($list)) return $list;
 369+
 370+ $keys = array_keys($list);
 371+ shuffle($keys);
 372+ $random = array();
 373+ foreach ($keys as $key)
 374+ $random[$key] = $list[$key];
 375+
 376+ return $random;
 377+ }
 378+
 379+ protected function preQueryUsers( $users ) {
 380+ $lb = new LinkBatch;
 381+ foreach ( $users as $translators ) {
 382+ foreach ( $translators as $user => $count ) {
 383+ $user = Title::capitalize( $user, NS_USER );
 384+ $lb->add( NS_USER, $user );
 385+ $lb->add( NS_USER_TALK, $user );
 386+ }
 387+ }
 388+ $lb->execute();
 389+ }
 390+
274391 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r89766Fu r89765 - forgot to commit stylesnikerabbit10:22, 9 June 2011

Status & tagging log