r53286 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r53285‎ | r53286 | r53287 >
Date:02:03, 15 July 2009
Author:demon
Status:resolved (Comments)
Tags:
Comment:
(bug 16497) Paginate Special:AllMessages
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialAllmessages.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/language/messages.inc (modified) (history)
  • /trunk/phase3/skins/common/allmessages.js (deleted) (history)
  • /trunk/phase3/skins/common/shared.css (modified) (history)
  • /trunk/phase3/skins/modern/main.css (modified) (history)
  • /trunk/phase3/skins/monobook/main.css (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/language/messages.inc
@@ -2058,8 +2058,11 @@
20592059 'allmessagescurrent',
20602060 'allmessagestext',
20612061 'allmessagesnotsupportedDB',
2062 - 'allmessagesfilter',
2063 - 'allmessagesmodified',
 2062+ 'allmessages-filter',
 2063+ 'allmessages-filter-unmodified',
 2064+ 'allmessages-filter-all',
 2065+ 'allmessages-filter-modified',
 2066+ 'allmessages-prefix',
20642067 ),
20652068 'thumbnails' => array(
20662069 'thumbnail-more',
Index: trunk/phase3/skins/monobook/main.css
@@ -1259,25 +1259,6 @@
12601260 font-weight:bold;
12611261 }
12621262
1263 -/* Allmessages table */
1264 -
1265 -#allmessagestable th {
1266 - background-color: #b2b2ff;
1267 -}
1268 -
1269 -#allmessagestable tr.orig {
1270 - background-color: #ffe2e2;
1271 -}
1272 -
1273 -#allmessagestable tr.new {
1274 - background-color: #e2ffe2;
1275 -}
1276 -
1277 -#allmessagestable tr.def {
1278 - background-color: #f0f0ff;
1279 -}
1280 -
1281 -
12821263 /* noarticletext */
12831264 div.noarticletext {
12841265 border: 1px solid #ccc;
Index: trunk/phase3/skins/modern/main.css
@@ -775,25 +775,6 @@
776776 font-weight:bold;
777777 }
778778
779 -/* Allmessages table */
780 -
781 -#allmessagestable th {
782 - background-color: #b2b2ff;
783 -}
784 -
785 -#allmessagestable tr.orig {
786 - background-color: #ffe2e2;
787 -}
788 -
789 -#allmessagestable tr.new {
790 - background-color: #e2ffe2;
791 -}
792 -
793 -#allmessagestable tr.def {
794 - background-color: #f0f0ff;
795 -}
796 -
797 -
798779 /* noarticletext */
799780 div.noarticletext {
800781 border: 1px solid #ccc;
Index: trunk/phase3/skins/common/allmessages.js
@@ -1,83 +0,0 @@
2 -var allmessages_nodelist = false;
3 -var allmessages_modified = false;
4 -var allmessages_timeout = false;
5 -var allmessages_running = false;
6 -
7 -function allmessagesmodified() {
8 - allmessages_modified = !allmessages_modified;
9 - allmessagesfilter();
10 -}
11 -
12 -function allmessagesfilter() {
13 - if ( allmessages_timeout )
14 - window.clearTimeout( allmessages_timeout );
15 -
16 - if ( !allmessages_running )
17 - allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
18 -}
19 -
20 -function allmessagesfilter_do() {
21 - if ( !allmessages_nodelist )
22 - return;
23 -
24 - var text = document.getElementById('allmessagesinput').value.toLowerCase();
25 - var nodef = allmessages_modified;
26 -
27 - allmessages_running = true;
28 -
29 - for ( var name in allmessages_nodelist ) {
30 - var nodes = allmessages_nodelist[name];
31 - var display = ( name.toLowerCase().indexOf( text ) == -1 ? 'none' : '' );
32 -
33 - for ( var i = 0; i < nodes.length; i++)
34 - nodes[i].style.display =
35 - ( nodes[i].className == "def" && nodef
36 - ? 'none' : display );
37 - }
38 -
39 - if ( text != document.getElementById('allmessagesinput').value.toLowerCase() ||
40 - nodef != allmessages_modified )
41 - allmessagesfilter_do(); // repeat
42 -
43 - allmessages_running = false;
44 -}
45 -
46 -function allmessagesfilter_init() {
47 - if ( allmessages_nodelist )
48 - return;
49 -
50 - var nodelist = new Array();
51 - var templist = new Array();
52 -
53 - var table = document.getElementById('allmessagestable');
54 - if ( !table ) return;
55 -
56 - var rows = document.getElementsByTagName('tr');
57 - for ( var i = 0; i < rows.length; i++ ) {
58 - var id = rows[i].getAttribute('id')
59 - if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
60 - templist[ id ] = rows[i];
61 - }
62 -
63 - var spans = table.getElementsByTagName('span');
64 - for ( var i = 0; i < spans.length; i++ ) {
65 - var id = spans[i].getAttribute('id')
66 - if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
67 - if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;
68 -
69 - var nodes = new Array();
70 - var row1 = templist[ id.replace('i', 'r1') ];
71 - var row2 = templist[ id.replace('i', 'r2') ];
72 -
73 - if ( row1 ) nodes[nodes.length] = row1;
74 - if ( row2 ) nodes[nodes.length] = row2;
75 - nodelist[ spans[i].firstChild.nodeValue ] = nodes;
76 - }
77 -
78 - var k = document.getElementById('allmessagesfilter');
79 - if (k) { k.style.display = ''; }
80 -
81 - allmessages_nodelist = nodelist;
82 -}
83 -
84 -hookEvent( "load", allmessagesfilter_init );
Index: trunk/phase3/skins/common/shared.css
@@ -620,6 +620,23 @@
621621 .imagelist .TablePager_col_img_description { white-space: normal }
622622 .imagelist th.TablePager_sort { background-color: #ccccff }
623623
 624+ /* Allmessages table */
 625+#allmessagestable .allmessages-customised td.am_default {
 626+ background-color: #fcffc4;
 627+}
 628+
 629+#allmessagestable tr.allmessages-customised:hover td.am_default {
 630+ background-color: #faff90;
 631+}
 632+
 633+#allmessagestable td.am_actual {
 634+ background-color: #e2ffe2;
 635+}
 636+
 637+#allmessagestable tr.allmessages-customised:hover + tr.allmessages-customised td.am_actual {
 638+ background-color: #b1ffb1;
 639+}
 640+
624641 /* filetoc */
625642 ul#filetoc {
626643 text-align: center;
Index: trunk/phase3/includes/AutoLoader.php
@@ -479,6 +479,7 @@
480480 'MWTidy' => 'includes/parser/Tidy.php',
481481
482482 # includes/specials
 483+ 'SpecialAllmessages' => 'includes/specials/SpecialAllmessages.php',
483484 'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
484485 'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
485486 'ContribsPager' => 'includes/specials/SpecialContributions.php',
Index: trunk/phase3/includes/DefaultSettings.php
@@ -1566,7 +1566,7 @@
15671567 * to ensure that client-side caches do not keep obsolete copies of global
15681568 * styles.
15691569 */
1570 -$wgStyleVersion = '231';
 1570+$wgStyleVersion = '232';
15711571
15721572
15731573 # Server-side caching:
Index: trunk/phase3/includes/specials/SpecialAllmessages.php
@@ -4,249 +4,380 @@
55 * @file
66 * @ingroup SpecialPage
77 */
8 -
9 -/**
10 - * Constructor.
11 - */
12 -function wfSpecialAllmessages() {
13 - global $wgOut, $wgRequest, $wgMessageCache;
14 - global $wgUseDatabaseMessages, $wgLang;
15 -
16 - # The page isn't much use if the MediaWiki namespace is not being used
17 - if( !$wgUseDatabaseMessages ) {
18 - $wgOut->addWikiMsg( 'allmessagesnotsupportedDB' );
19 - return;
 8+class SpecialAllmessages extends SpecialPage {
 9+
 10+ /**
 11+ * Constructor
 12+ */
 13+ public function __construct() {
 14+ parent::__construct( 'Allmessages' );
2015 }
 16+
 17+ /**
 18+ * Execute
 19+ */
 20+ function execute( $par ) {
 21+ global $wgOut, $wgRequest;
 22+
 23+ $this->setHeaders();
 24+
 25+ global $wgUseDatabaseMessages;
 26+ if( !$wgUseDatabaseMessages ) {
 27+ $wgOut->addWikiMsg( 'allmessagesnotsupportedDB' );
 28+ return;
 29+ } else {
 30+ $this->outputHeader( 'allmessagestext' );
 31+ }
2132
22 - wfProfileIn( __METHOD__ );
23 -
24 - wfProfileIn( __METHOD__ . '-setup' );
25 - $ot = $wgRequest->getText( 'ot' );
26 -
27 - $navText = wfMsg( 'allmessagestext' );
28 -
29 - # Make sure all extension messages are available
30 -
31 - $wgMessageCache->loadAllMessages();
32 -
33 - $sortedArray = Language::getMessagesFor( 'en' );
34 - ksort( $sortedArray );
35 -
36 - $messages = array();
37 - foreach( $sortedArray as $key => $value ) {
38 - $messages[$key]['enmsg'] = $value;
39 - $messages[$key]['statmsg'] = wfMsgReal( $key, array(), false, false, false );
40 - $messages[$key]['msg'] = wfMsgNoTrans( $key );
41 - $sortedArray[$key] = NULL; // trade bytes from $sortedArray to this
 33+ $this->filter = $wgRequest->getVal( 'filter', 'all' );
 34+ $this->prefix = $wgRequest->getVal( 'prefix', '' );
4235
 36+ $this->table = new AllmessagesTablePager( $this,
 37+ $conds=array(),
 38+ wfGetLangObj( $wgRequest->getVal( 'lang', false ) ) );
 39+
 40+ $this->langCode = $this->table->lang->getCode();
 41+
 42+ $wgOut->addHTML( $this->buildForm() .
 43+ $this->table->getNavigationBar() .
 44+ $this->table->getLimitForm() .
 45+ $this->table->getBody() .
 46+ $this->table->getNavigationBar() );
 47+
4348 }
44 - unset($sortedArray); // trade bytes from $sortedArray to this
45 -
46 - wfProfileOut( __METHOD__ . '-setup' );
47 -
48 - wfProfileIn( __METHOD__ . '-output' );
49 - $wgOut->addScriptFile( 'allmessages.js' );
50 - $title = SpecialPage::getTitleFor( 'Allmessages' );
51 - if ( $ot == 'php' ) {
52 - $navText .= wfAllMessagesMakePhp( $messages );
53 - $wgOut->addHTML( $wgLang->pipeList( array(
54 - 'PHP',
55 - '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'html' ) ) . '">HTML</a>',
56 - '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'xml' ) ) . '">XML</a>' .
57 - '<pre>' . htmlspecialchars( $navText ) . '</pre>'
58 - ) ) );
59 - } else if ( $ot == 'xml' ) {
60 - $wgOut->disable();
61 - header( 'Content-type: text/xml' );
62 - echo wfAllMessagesMakeXml( $messages );
63 - } else {
64 - $wgOut->addHTML( $wgLang->pipeList( array(
65 - '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'php' ) ) . '">PHP</a>',
66 - 'HTML',
67 - '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'xml' ) ) . '">XML</a>'
68 - ) ) );
69 - $wgOut->addWikiText( $navText );
70 - $wgOut->addHTML( wfAllMessagesMakeHTMLText( $messages ) );
 49+
 50+ function buildForm() {
 51+ $url = $this->getTitle()->escapeLocalURL();
 52+ $languages = Language::getLanguageNames( false );
 53+ ksort( $languages );
 54+
 55+ $out = "<form method=\"get\" action=\"$url\"><fieldset>\n" .
 56+ Xml::element( 'legend', null, wfMsg( 'allmessages' ) ) . "<table><tr>\n" .
 57+ "<td class=\"mw-label\">" .
 58+ Xml::label( wfMsg('allmessages-prefix'), 'am-form-prefix' ) .
 59+ "</td>\n<td class=\"mw-input\">" .
 60+ Xml::input( 'prefix', 20, str_replace('_',' ',$this->prefix), array( 'id' => 'am-form-prefix' ) ) .
 61+ "</select>" .
 62+ "</td>\n</tr><tr>\n<td class='mw-label'>" .
 63+ Xml::label( wfMsg('allmessages-filter'), 'am-form-filter' ) .
 64+ "</td>\n<td class='mw-input'>" .
 65+ Xml::radioLabel( wfMsg('allmessages-filter-unmodified'),
 66+ 'filter',
 67+ 'unmodified',
 68+ 'am-form-filter-unmodified',
 69+ ( $this->filter == 'unmodified' ? true : false )
 70+ ) .
 71+ Xml::radioLabel( wfMsg('allmessages-filter-all'),
 72+ 'filter',
 73+ 'all',
 74+ 'am-form-filter-all',
 75+ ( $this->filter == 'all' ? true : false )
 76+ ) .
 77+ Xml::radioLabel( wfMsg('allmessages-filter-modified'),
 78+ 'filter',
 79+ 'modified',
 80+ 'am-form-filter-modified',
 81+ ( $this->filter == 'modified' ? true : false )
 82+ ) .
 83+ "</td>\n</tr><tr>\n<td class=\"mw-label\">" .
 84+ Xml::label( wfMsg('yourlanguage'), 'am-form-lang' ) .
 85+ "</td>\n<td class=\"mw-input\">" .
 86+ Xml::openElement( 'select', array( 'id' => 'am-form-lang', 'name' => 'lang' ) );
 87+ foreach( $languages as $lang => $name ) {
 88+ $selected = $lang == $this->langCode ? 'selected="selected"' : '';
 89+ $out .= "<option value=\"$lang\" $selected>$name</option>\n";
 90+ }
 91+ $out .= "</td>\n</tr><tr>\n<td></td><td>" . Xml::submitButton( wfMsg('allpagessubmit') ) .
 92+ "</table>" .
 93+ $this->table->getHiddenFields( array( 'title', 'prefix', 'filter', 'lang' ) ) .
 94+ "</fieldset></form>";
 95+ return $out;
7196 }
72 - wfProfileOut( __METHOD__ . '-output' );
73 -
74 - wfProfileOut( __METHOD__ );
7597 }
7698
77 -function wfAllMessagesMakeXml( &$messages ) {
78 - global $wgLang;
79 - $lang = $wgLang->getCode();
80 - $txt = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
81 - $txt .= "<messages lang=\"$lang\">\n";
82 - foreach( $messages as $key => $m ) {
83 - $txt .= "\t" . Xml::element( 'message', array( 'name' => $key ), $m['msg'] ) . "\n";
84 - $messages[$key] = NULL; // trade bytes
85 - }
86 - $txt .= "</messages>";
87 - return $txt;
88 -}
89 -
90 -/**
91 - * Create the messages array, formatted in PHP to copy to language files.
92 - * @param $messages Messages array.
93 - * @return The PHP messages array.
94 - * @todo Make suitable for language files.
 99+/* use TablePager for prettified output. We have to pretend that we're
 100+ * getting data from a table when in fact not all of it comes from the database.
95101 */
96 -function wfAllMessagesMakePhp( &$messages ) {
97 - global $wgLang;
98 - $txt = "\n\n\$messages = array(\n";
99 - foreach( $messages as $key => $m ) {
100 - if( $wgLang->getCode() != 'en' && $m['msg'] == $m['enmsg'] ) {
101 - continue;
102 - } else if ( wfEmptyMsg( $key, $m['msg'] ) ) {
103 - $m['msg'] = '';
104 - $comment = ' #empty';
 102+class AllmessagesTablePager extends TablePager {
 103+
 104+ var $messages = NULL;
 105+ var $talkPages = NULL;
 106+
 107+ function __construct( $page, $conds, $langObj = NULL ) {
 108+ parent::__construct();
 109+ $this->mIndexField = 'am_title';
 110+ $this->mPage = $page;
 111+ $this->mConds = $conds;
 112+ $this->mDefaultDirection = true; //always sort ascending
 113+
 114+ global $wgLang, $wgContLang, $wgRequest;
 115+
 116+ $this->talk = $wgLang->lc( htmlspecialchars( wfMsg( 'talkpagelinktext' ) ) );
 117+
 118+ $this->lang = ( $langObj ? $langObj : $wgContLang );
 119+ $this->langcode = $this->lang->getCode();
 120+ $this->foreign = $this->langcode != $wgContLang->getCode();
 121+
 122+ if( $wgRequest->getVal( 'filter', 'all' ) === 'all' ){
 123+ $this->custom = NULL; //So won't match in either case
105124 } else {
106 - $comment = '';
 125+ $this->custom = $wgRequest->getVal( 'filter' ) == 'unmodified' ? 1 : 0;
107126 }
108 - $txt .= "'$key' => '" . preg_replace( '/(?<!\\\\)\'/', "\'", $m['msg']) . "',$comment\n";
109 - $messages[$key] = NULL; // trade bytes
 127+
 128+ $prefix = $wgLang->ucfirst( $wgRequest->getVal( 'prefix', '' ) );
 129+ $prefix = $prefix != '' ? Title::makeTitleSafe( NS_MEDIAWIKI, $wgRequest->getVal( 'prefix', NULL ) ) : NULL;
 130+ if( $prefix !== NULL ){
 131+ $this->prefix = '/^' . preg_quote( $prefix->getDBkey() ) . '/i';
 132+ } else {
 133+ $this->prefix = false;
 134+ }
 135+ $this->getSkin();
 136+
 137+ //The suffix that may be needed for message names if we're in a
 138+ //different language (eg [[MediaWiki:Foo/fr]]: $suffix = '/fr'
 139+ if( $this->foreign ) {
 140+ $this->suffix = '/' . $this->langcode;
 141+ } else {
 142+ $this->suffix = '';
 143+ }
110144 }
111 - $txt .= ');';
112 - return $txt;
113 -}
114 -
115 -/**
116 - * Create a list of messages, formatted in HTML as a list of messages and values and showing differences between the default language file message and the message in MediaWiki: namespace.
117 - * @param $messages Messages array.
118 - * @return The HTML list of messages.
119 - */
120 -function wfAllMessagesMakeHTMLText( &$messages ) {
121 - global $wgLang, $wgContLang, $wgUser;
122 - wfProfileIn( __METHOD__ );
123 -
124 - $sk = $wgUser->getSkin();
125 - $talk = wfMsg( 'talkpagelinktext' );
126 -
127 - $input = Xml::element( 'input', array(
128 - 'type' => 'text',
129 - 'id' => 'allmessagesinput',
130 - 'onkeyup' => 'allmessagesfilter()'
131 - ), '' );
132 - $checkbox = Xml::element( 'input', array(
133 - 'type' => 'button',
134 - 'value' => wfMsgHtml( 'allmessagesmodified' ),
135 - 'id' => 'allmessagescheckbox',
136 - 'onclick' => 'allmessagesmodified()'
137 - ), '' );
138 -
139 - $txt = '<span id="allmessagesfilter" style="display: none;">' . wfMsgHtml( 'allmessagesfilter' ) .
140 - " {$input}{$checkbox} " . '</span>';
141 -
142 - $txt .= '
143 -<table border="1" cellspacing="0" width="100%" id="allmessagestable">
144 - <tr>
145 - <th rowspan="2">' . wfMsgHtml( 'allmessagesname' ) . '</th>
146 - <th>' . wfMsgHtml( 'allmessagesdefault' ) . '</th>
147 - </tr>
148 - <tr>
149 - <th>' . wfMsgHtml( 'allmessagescurrent' ) . '</th>
150 - </tr>';
151 -
152 - wfProfileIn( __METHOD__ . "-check" );
153 -
154 - # This is a nasty hack to avoid doing independent existence checks
155 - # without sending the links and table through the slow wiki parser.
156 - $pageExists = array(
157 - NS_MEDIAWIKI => array(),
158 - NS_MEDIAWIKI_TALK => array()
159 - );
160 - $dbr = wfGetDB( DB_SLAVE );
161 - $res = $dbr->select( 'page',
162 - array( 'page_namespace', 'page_title' ),
163 - array( 'page_namespace' => array(NS_MEDIAWIKI,NS_MEDIAWIKI_TALK) ),
164 - __METHOD__,
165 - array( 'USE INDEX' => 'name_title' )
166 - );
167 - while( $s = $dbr->fetchObject( $res ) ) {
168 - $pageExists[$s->page_namespace][$s->page_title] = 1;
 145+
 146+ function getAllMessages( $desc ){
 147+
 148+ wfProfileIn( __METHOD__ . '-cache' );
 149+
 150+ # Make sure all extension messages are available
 151+ global $wgMessageCache;
 152+ $wgMessageCache->loadAllMessages( 'en' );
 153+ $sortedArray = Language::getMessagesFor( 'en' );
 154+ if( $desc ){
 155+ krsort( $sortedArray );
 156+ } else {
 157+ ksort( $sortedArray );
 158+ }
 159+
 160+ $this->messages = array();
 161+ foreach( $sortedArray as $key => $value ) {
 162+ // All messages start with lowercase, but wikis might have both
 163+ // upper and lowercase MediaWiki: pages if $wgCapitalLinks=false.
 164+ $ukey = $this->lang->ucfirst( $key );
 165+
 166+ // The value without any overrides from the MediaWiki: namespace
 167+ $this->messages[$ukey]['default'] = wfMsgGetKey( $key, /*useDB*/false, $this->langcode, false );
 168+
 169+ // The message that's actually used by the site
 170+ $this->messages[$ukey]['actual'] = wfMsgGetKey( $key, /*useDB*/true, $this->langcode, false );
 171+
 172+ $this->messages[$ukey]['customised'] = 0; //for now
 173+
 174+ $sortedArray[$key] = NULL; // trade bytes from $sortedArray to this
 175+ }
 176+
 177+ wfProfileOut( __METHOD__ . '-cache' );
 178+
 179+ return true;
169180 }
170 - $dbr->freeResult( $res );
171 - wfProfileOut( __METHOD__ . "-check" );
 181+
 182+ # We only need a list of which messages have *been* customised;
 183+ # their content is already in the message cache.
 184+ function markCustomisedMessages(){
 185+ $this->talkPages = array();
 186+
 187+ wfProfileIn( __METHOD__ . "-db" );
172188
173 - wfProfileIn( __METHOD__ . "-output" );
174 -
175 - $i = 0;
176 -
177 - foreach( $messages as $key => $m ) {
178 - $title = $wgLang->ucfirst( $key );
179 - if( $wgLang->getCode() != $wgContLang->getCode() ) {
180 - $title .= '/' . $wgLang->getCode();
 189+ $dbr = wfGetDB( DB_SLAVE );
 190+ $res = $dbr->select( 'page',
 191+ array( 'page_namespace', 'page_title' ),
 192+ array( 'page_namespace' => array(NS_MEDIAWIKI,NS_MEDIAWIKI_TALK) ),
 193+ __METHOD__,
 194+ array( 'USE INDEX' => 'name_title' )
 195+ );
 196+
 197+ while( $s = $dbr->fetchObject( $res ) ) {
 198+ if( $s->page_namespace == NS_MEDIAWIKI ){
 199+ if( $this->foreign ){
 200+ $title = explode( '/', $s->page_title );
 201+ if( $this->langcode == $title[1] && array_key_exists( $title[0], $this->messages ) ){
 202+ $this->messages["{$title[0]}"]['customised'] = 1;
 203+ }
 204+ } else if( array_key_exists( $s->page_title , $this->messages ) ){
 205+ $this->messages[$s->page_title]['customised'] = 1;
 206+ }
 207+ } else if( $s->page_namespace == NS_MEDIAWIKI_TALK ){
 208+ $this->talkPages[$s->page_title] = 1;
 209+ }
181210 }
 211+ $dbr->freeResult( $res );
 212+
 213+ wfProfileOut( __METHOD__ . "-db" );
 214+
 215+ return true;
 216+ }
 217+
 218+ /* This function normally does a database query to get the results; we need
 219+ * to make a pretend result using a FakeResultWrapper.
 220+ */
 221+ function reallyDoQuery( $offset , $limit , $descending ){
 222+ $mResult = new FakeResultWrapper( array() );
 223+
 224+ if( !$this->messages ) $this->getAllMessages( $descending );
 225+ if( $this->talkPages === NULL ) $this->markCustomisedMessages();
 226+
 227+ $count = 0;
 228+ foreach( $this->messages as $key => $value ){
 229+ if( $value['customised'] !== $this->custom &&
 230+ ( $descending && ( $key < $offset || !$offset ) || !$descending && $key > $offset ) &&
 231+ (( $this->prefix && preg_match( $this->prefix, $key ) ) || $this->prefix === false )
 232+ ){
 233+ $mResult->result[] = array( 'am_title' => $key,
 234+ 'am_actual' => $value['actual'],
 235+ 'am_default' => $value['default'],
 236+ 'am_customised' => $value['customised'],
 237+ );
 238+ unset( $this->messages[$key] ); // save a few bytes
 239+ $count++;
 240+ }
 241+ if( $count == $limit ) break;
 242+ }
 243+ unset( $this->messages ); //no longer needed, free up some memory
 244+ return $mResult;
 245+ }
 246+
 247+ function getStartBody() {
 248+ return "<table border=\"1\" class=\"TablePager\" style=\"width:100%;\" id=\"allmessagestable\"><thead>\n<tr>" .
 249+ "<th rowspan=\"2\">" . wfMsg('allmessagesname') . "</th><th>" . wfMsg('allmessagesdefault') .
 250+ "</tr>\n<tr><th>" . wfMsg('allmessagescurrent') . "</th></tr>\n";
 251+ }
 252+
 253+ function formatValue( $field , $value ){
 254+ global $wgLang;
 255+ switch( $field ){
 256+
 257+ case 'am_title' :
 258+
 259+ $title = Title::makeTitle( NS_MEDIAWIKI, $value . $this->suffix );
 260+ $talk = Title::makeTitle( NS_MEDIAWIKI_TALK, $value . $this->suffix );
182261
183 - $titleObj = Title::makeTitle( NS_MEDIAWIKI, $title );
184 - $talkPage = Title::makeTitle( NS_MEDIAWIKI_TALK, $title );
185 -
186 - $changed = ( $m['statmsg'] != $m['msg'] );
187 - $message = htmlspecialchars( $m['statmsg'] );
188 - $mw = htmlspecialchars( $m['msg'] );
189 -
190 - $linkText = "<span id=\"sp-allmessages-i-$i\">" . htmlspecialchars( $key ) . '</span>';
191 -
192 - if( array_key_exists( $title, $pageExists[NS_MEDIAWIKI] ) ) {
193 - // FIXME: the span should be taken care of in $customAttribs, shouldn't it?
194 - $pageLink = $sk->linkKnown(
195 - $titleObj,
196 - $linkText
197 - );
198 - } else {
199 - $pageLink = $sk->link(
200 - $titleObj,
201 - $linkText,
202 - array(),
203 - array(),
204 - array( 'broken' )
205 - );
 262+ if( $this->mCurrentRow->am_customised ){
 263+ $title = $this->mSkin->linkKnown( $title, $wgLang->lcfirst( $value ) );
 264+ } else {
 265+ $title = $this->mSkin->link( $title,
 266+ $wgLang->lcfirst( $value ),
 267+ array(),
 268+ array(),
 269+ array( 'broken' ) );
 270+ }
 271+ if( array_key_exists( $talk->getDBkey() , $this->talkPages ) ) {
 272+ $talk = $this->mSkin->linkKnown( $talk , $this->talk );
 273+ } else {
 274+ $talk = $this->mSkin->link( $talk,
 275+ $this->talk,
 276+ array(),
 277+ array(),
 278+ array( 'broken' ) );
 279+ }
 280+ return $title . ' (' . $talk . ')';
 281+
 282+ case 'am_default' :
 283+ return Sanitizer::escapeHtmlAllowEntities( $value, ENT_QUOTES );
 284+ case 'am_actual' :
 285+ return Sanitizer::escapeHtmlAllowEntities( $value, ENT_QUOTES );
206286 }
207 - if( array_key_exists( $title, $pageExists[NS_MEDIAWIKI_TALK] ) ) {
208 - $talkLink = $sk->linkKnown( $talkPage, htmlspecialchars( $talk ) );
209 - } else {
210 - $talkLink = $sk->link(
211 - $talkPage,
212 - htmlspecialchars( $talk ),
213 - array(),
214 - array(),
215 - array( 'broken' )
216 - );
 287+ return '';
 288+ }
 289+
 290+ function formatRow( $row ){
 291+ //Do all the normal stuff
 292+ $s = parent::formatRow( $row );
 293+
 294+ //But if there's a customised message, add that too.
 295+ if( $row->am_customised ){
 296+ $s .= Xml::openElement( 'tr', $this->getRowAttrs( $row, true ) );
 297+ $formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
 298+ if ( $formatted == '' ) {
 299+ $formatted = '&nbsp;';
 300+ }
 301+ $s .= Xml::tags( 'td', $this->getCellAttrs( 'am_actual', $row->am_actual ), $formatted )
 302+ . "</tr>\n";
217303 }
218 -
219 - $anchor = 'msg_' . htmlspecialchars( strtolower( $title ) );
220 - $anchor = "<a id=\"$anchor\" name=\"$anchor\"></a>";
221 -
222 - if( $changed ) {
223 - $txt .= "
224 - <tr class=\"orig\" id=\"sp-allmessages-r1-$i\">
225 - <td rowspan=\"2\">
226 - $anchor$pageLink<br />$talkLink
227 - </td><td>
228 - $message
229 - </td>
230 - </tr><tr class=\"new\" id=\"sp-allmessages-r2-$i\">
231 - <td>
232 - $mw
233 - </td>
234 - </tr>";
 304+ return $s;
 305+ }
 306+
 307+ function getRowAttrs( $row, $isSecond=false ){
 308+ $arr = array();
 309+ global $wgLang;
 310+ if( $row->am_customised ){
 311+ $arr['class'] = 'allmessages-customised';
 312+ }
 313+ if( !$isSecond ){
 314+ $arr['id'] = Sanitizer::escapeId( 'msg_' . $wgLang->lcfirst( $row->am_title ) );
 315+ }
 316+ return $arr;
 317+ }
 318+
 319+ function getCellAttrs( $field, $value ){
 320+ if( $this->mCurrentRow->am_customised && $field == 'am_title' ){
 321+ return array( 'rowspan' => '2', 'class' => $field );
235322 } else {
236 - $txt .= "
237 - <tr class=\"def\" id=\"sp-allmessages-r1-$i\">
238 - <td>
239 - $anchor$pageLink<br />$talkLink
240 - </td><td>
241 - $mw
242 - </td>
243 - </tr>";
 323+ return array( 'class' => $field );
244324 }
245 - $messages[$key] = NULL; // trade bytes
246 - $i++;
247325 }
248 - $txt .= '</table>';
249 - wfProfileOut( __METHOD__ . '-output' );
 326+
 327+ // This is not actually used, as getStartBody is overridden above
 328+ function getFieldNames() {
 329+ return array( 'am_title' => wfMsg('allmessagesname'),
 330+ 'am_default' => wfMsg('allmessagesdefault') );
 331+ }
 332+ function getTitle() {
 333+ return SpecialPage::getTitleFor( 'Allmessages', false );
 334+ }
 335+ function isFieldSortable( $x ){
 336+ return false;
 337+ }
 338+ function getDefaultSort(){
 339+ return '';
 340+ }
 341+ function getQueryInfo(){
 342+ return '';
 343+ }
 344+}
 345+/* Overloads the relevant methods of the real ResultsWrapper so it
 346+ * doesn't go anywhere near an actual database.
 347+ */
 348+class FakeResultWrapper extends ResultWrapper {
 349+
 350+ var $result = array();
 351+ var $db = NULL; //And it's going to stay that way :D
 352+ var $pos = 0;
 353+ var $currentRow = NULL;
 354+
 355+ function __construct( $array ){
 356+ $this->result = $array;
 357+ }
 358+
 359+ function numRows() {
 360+ return count( $this->result );
 361+ }
 362+
 363+ function fetchRow() {
 364+ $this->currentRow = $this->result[$this->pos++];
 365+ return $this->currentRow;
 366+ }
 367+
 368+ function seek( $row ) {
 369+ $this->pos = $row;
 370+ }
250371
251 - wfProfileOut( __METHOD__ );
252 - return $txt;
 372+ function free() {}
 373+
 374+ // Callers want to be able to access fields with $this->fieldName
 375+ function fetchObject(){
 376+ $this->currentRow = $this->result[$this->pos++];
 377+ return (object)$this->currentRow;
 378+ }
 379+
 380+ function rewind() {
 381+ $this->pos = 0;
 382+ $this->currentRow = NULL;
 383+ }
253384 }
Index: trunk/phase3/includes/SpecialPage.php
@@ -145,7 +145,7 @@
146146
147147 # Wiki data and tools
148148 'Statistics' => 'SpecialStatistics',
149 - 'Allmessages' => array( 'SpecialPage', 'Allmessages' ),
 149+ 'Allmessages' => 'SpecialAllmessages',
150150 'Version' => 'SpecialVersion',
151151 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
152152 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -3047,8 +3047,11 @@
30483048 'allmessagestext' => 'This is a list of system messages available in the MediaWiki namespace.
30493049 Please visit [http://www.mediawiki.org/wiki/Localisation MediaWiki Localisation] and [http://translatewiki.net translatewiki.net] if you wish to contribute to the generic MediaWiki localisation.',
30503050 'allmessagesnotsupportedDB' => "This page cannot be used because '''\$wgUseDatabaseMessages''' has been disabled.",
3051 -'allmessagesfilter' => 'Message name filter:',
3052 -'allmessagesmodified' => 'Show only modified',
 3051+'allmessages-filter' => 'Filter by customisation state:',
 3052+'allmessages-filter-unmodified' => 'Unmodified',
 3053+'allmessages-filter-all' => 'All',
 3054+'allmessages-filter-modified' => 'Modified',
 3055+'allmessages-prefix' => 'Filter by prefix:',
30533056
30543057 # Thumbnails
30553058 'thumbnail-more' => 'Enlarge',
Index: trunk/phase3/RELEASE-NOTES
@@ -254,6 +254,7 @@
255255 * Log in and log out links no longer return to page view when clicked from
256256 history view, edit page, or something similar
257257 * (bug 19513) RTL fixes for new Search UI
 258+* (bug 16497) Special:Allmessages is paginated
258259
259260 == API changes in 1.16 ==
260261

Follow-up revisions

RevisionCommit summaryAuthorDate
r53309Followup to r53286: Fix trailing whitespace.demon11:48, 15 July 2009
r533382nd followup to r53286, indentation fixes.demon22:48, 15 July 2009
r53417Follow-up to r53286...siebrand21:38, 17 July 2009
r53441Follow-up r53286: Fix some issues:...raymond13:50, 18 July 2009
r53444Follow-up r53286: More fixes for invalid HTMLraymond14:36, 18 July 2009
r53445Follow-up r53286: No need to create a label without following input element.raymond14:59, 18 July 2009

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r45141(bug 16497) Cut down on heavy memory usage hereaaron21:28, 28 December 2008

Comments

#Comment by Nikerabbit (talk | contribs)   06:28, 15 July 2009

Please fix indentation and trailing whitespace in SpecialAllmessages.php

#Comment by 😂 (talk | contribs)   11:48, 15 July 2009

Fixed whitespace in r53309. Didn't really see an indentation issue?

#Comment by Nikerabbit (talk | contribs)   12:22, 15 July 2009

In buildForm there is mix of spaces and tabs, and in some places there are multiple tabs for one indentation level (you can't align part of lines to same position with tabs)

#Comment by Raymond (talk | contribs)   13:51, 18 July 2009

Issues with invalid HTML, code styling etc fixed in r53441.

#Comment by Raymond (talk | contribs)   19:43, 23 July 2009

Fixed with r53688 by ialex (applied ^demon's patch)

Status & tagging log