r39416 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r39415‎ | r39416 | r39417 >
Date:17:55, 15 August 2008
Author:aaron
Status:old
Tags:
Comment:
Rewrite allpages to use a "tree" of index range subpages (similar to the starting page) rather than one increasingly large range list (bug 13902)
Modified paths:
  • /trunk/phase3/includes/specials/SpecialAllpages.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/language/messages.inc (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/language/messages.inc
@@ -1285,6 +1285,7 @@
12861286 'nextpage',
12871287 'prevpage',
12881288 'allpagesfrom',
 1289+ 'allpagesto',
12891290 'allarticles',
12901291 'allinnamespace',
12911292 'allnotinnamespace',
Index: trunk/phase3/includes/specials/SpecialAllpages.php
@@ -13,7 +13,8 @@
1414 global $wgRequest, $wgOut, $wgContLang;
1515
1616 # GET values
17 - $from = $wgRequest->getVal( 'from' );
 17+ $from = $wgRequest->getVal( 'from', '' );
 18+ $to = $wgRequest->getVal( 'to', '' );
1819 $namespace = $wgRequest->getInt( 'namespace' );
1920
2021 $namespaces = $wgContLang->getNamespaces();
@@ -24,14 +25,8 @@
2526 wfMsg( 'allinnamespace', str_replace( '_', ' ', $namespaces[$namespace] ) ) :
2627 wfMsg( 'allarticles' )
2728 );
28 -
29 - if ( isset($par) ) {
30 - $indexPage->showChunk( $namespace, $par, $specialPage->including() );
31 - } elseif ( isset($from) ) {
32 - $indexPage->showChunk( $namespace, $from, $specialPage->including() );
33 - } else {
34 - $indexPage->showToplevel ( $namespace, $specialPage->including() );
35 - }
 29+
 30+ $indexPage->showToplevel( $namespace, $from, $to, $specialPage->including() );
3631 }
3732
3833 /**
@@ -40,9 +35,14 @@
4136 */
4237 class SpecialAllpages {
4338 /**
44 - * Maximum number of pages to show on single subpage.
 39+ * Maximum number of pages to show on single list subpage.
4540 */
46 - protected $maxPerPage = 960;
 41+ protected $maxPerPage = 345;
 42+
 43+ /**
 44+ * Maximum number of pages to show on single index subpage.
 45+ */
 46+ protected $maxLineCount = 200;
4747
4848 /**
4949 * Name of this special page. Used to make title objects that reference back
@@ -50,17 +50,13 @@
5151 */
5252 protected $name = 'Allpages';
5353
54 - /**
55 - * Determines, which message describes the input field 'nsfrom'.
56 - */
57 - protected $nsfromMsg = 'allpagesfrom';
58 -
5954 /**
6055 * HTML for the top form
6156 * @param integer $namespace A namespace constant (default NS_MAIN).
62 - * @param string $from Article name we are starting listing at.
 57+ * @param string $from dbKey we are starting listing at.
 58+ * @param string $to dbKey we are ending listing at.
6359 */
64 -function namespaceForm ( $namespace = NS_MAIN, $from = '' ) {
 60+function namespaceForm( $namespace = NS_MAIN, $from = '', $to = '' ) {
6561 global $wgScript;
6662 $t = SpecialPage::getTitleFor( $this->name );
6763
@@ -72,14 +68,22 @@
7369 $out .= Xml::openElement( 'table', array( 'id' => 'nsselect', 'class' => 'allpages' ) );
7470 $out .= "<tr>
7571 <td class='mw-label'>" .
76 - Xml::label( wfMsg( $this->nsfromMsg ), 'nsfrom' ) .
 72+ Xml::label( wfMsg( 'allpagesfrom' ), 'nsfrom' ) .
7773 "</td>
7874 <td class='mw-input'>" .
79 - Xml::input( 'from', 20, $from, array( 'id' => 'nsfrom' ) ) .
 75+ Xml::input( 'from', 30, str_replace('_',' ',$from), array( 'id' => 'nsfrom' ) ) .
8076 "</td>
8177 </tr>
8278 <tr>
8379 <td class='mw-label'>" .
 80+ Xml::label( wfMsg( 'allpagesto' ), 'nsto' ) .
 81+ "</td>
 82+ <td class='mw-input'>" .
 83+ Xml::input( 'to', 30, str_replace('_',' ',$to), array( 'id' => 'nsto' ) ) .
 84+ "</td>
 85+ </tr>
 86+ <tr>
 87+ <td class='mw-label'>" .
8488 Xml::label( wfMsg( 'namespace' ), 'namespace' ) .
8589 "</td>
8690 <td class='mw-input'>" .
@@ -97,7 +101,7 @@
98102 /**
99103 * @param integer $namespace (default NS_MAIN)
100104 */
101 -function showToplevel ( $namespace = NS_MAIN, $including = false ) {
 105+function showToplevel( $namespace = NS_MAIN, $from = '', $to = '', $including = false ) {
102106 global $wgOut, $wgContLang;
103107 $align = $wgContLang->isRtl() ? 'left' : 'right';
104108
@@ -107,45 +111,54 @@
108112 $dbr = wfGetDB( DB_SLAVE );
109113 $out = "";
110114 $where = array( 'page_namespace' => $namespace );
 115+
 116+ $from = Title::makeTitleSafe( $namespace, $from );
 117+ $to = Title::makeTitleSafe( $namespace, $to );
 118+ $from = $from ? $from->getDBKey() : null;
 119+ $to = $to ? $to->getDBKey() : null;
 120+
 121+ if( isset($from) )
 122+ $where[] = 'page_title >= '.$dbr->addQuotes( $from );
 123+ if( isset($to) )
 124+ $where[] = 'page_title <= '.$dbr->addQuotes( $to );
111125
112126 global $wgMemc;
113 - $key = wfMemcKey( 'allpages', 'ns', $namespace );
 127+ $key = wfMemcKey( 'allpages', 'ns', $namespace, $from, $to );
114128 $lines = $wgMemc->get( $key );
 129+
 130+ $count = $dbr->estimateRowCount( 'page', '*', $where, __METHOD__ );
 131+ $maxPerSubpage = intval($count/$this->maxLineCount);
 132+ $maxPerSubpage = max($maxPerSubpage,$this->maxPerPage);
115133
116134 if( !is_array( $lines ) ) {
117135 $options = array( 'LIMIT' => 1 );
118 - if ( ! $dbr->implicitOrderby() ) {
119 - $options['ORDER BY'] = 'page_title';
120 - }
 136+ $options['ORDER BY'] = 'page_title ASC';
121137 $firstTitle = $dbr->selectField( 'page', 'page_title', $where, __METHOD__, $options );
122138 $lastTitle = $firstTitle;
123 -
124139 # This array is going to hold the page_titles in order.
125140 $lines = array( $firstTitle );
126 -
127141 # If we are going to show n rows, we need n+1 queries to find the relevant titles.
128142 $done = false;
129 - for( $i = 0; !$done; ++$i ) {
 143+ while( !$done ) {
130144 // Fetch the last title of this chunk and the first of the next
131145 $chunk = is_null( $lastTitle )
132146 ? ''
133147 : 'page_title >= ' . $dbr->addQuotes( $lastTitle );
134 - $res = $dbr->select(
135 - 'page', /* FROM */
 148+ $chunk = array($chunk);
 149+ $res = $dbr->select( 'page', /* FROM */
136150 'page_title', /* WHAT */
137 - $where + array($chunk),
 151+ array_merge($where,$chunk),
138152 __METHOD__,
139 - array ('LIMIT' => 2, 'OFFSET' => $this->maxPerPage - 1, 'ORDER BY' => 'page_title') );
 153+ array ('LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC')
 154+ );
140155
141 - if ( $s = $dbr->fetchObject( $res ) ) {
 156+ if( $s = $dbr->fetchObject( $res ) ) {
142157 array_push( $lines, $s->page_title );
143158 } else {
144159 // Final chunk, but ended prematurely. Go back and find the end.
145160 $endTitle = $dbr->selectField( 'page', 'MAX(page_title)',
146 - array(
147 - 'page_namespace' => $namespace,
148 - $chunk
149 - ), __METHOD__ );
 161+ array_merge($where,$chunk),
 162+ __METHOD__ );
150163 array_push( $lines, $endTitle );
151164 $done = true;
152165 }
@@ -165,35 +178,35 @@
166179 // If there are only two or less sections, don't even display them.
167180 // Instead, display the first section directly.
168181 if( count( $lines ) <= 2 ) {
169 - $this->showChunk( $namespace, '', $including );
 182+ $this->showChunk( $namespace, $from, $to, $including );
170183 return;
171184 }
172185
173186 # At this point, $lines should contain an even number of elements.
174187 $out .= "<table class='allpageslist' style='background: inherit;'>";
175 - while ( count ( $lines ) > 0 ) {
176 - $inpoint = array_shift ( $lines );
177 - $outpoint = array_shift ( $lines );
178 - $out .= $this->showline ( $inpoint, $outpoint, $namespace, false );
 188+ while( count ( $lines ) > 0 ) {
 189+ $inpoint = array_shift( $lines );
 190+ $outpoint = array_shift( $lines );
 191+ $out .= $this->showline( $inpoint, $outpoint, $namespace );
179192 }
180193 $out .= '</table>';
181 - $nsForm = $this->namespaceForm( $namespace, '', false );
 194+ $nsForm = $this->namespaceForm( $namespace, $from, $to );
182195
183196 # Is there more?
184 - if ( $including ) {
 197+ if( $including ) {
185198 $out2 = '';
186199 } else {
187 - $morelinks = '';
188 - if ( $morelinks != '' ) {
 200+ if( isset($from) || isset($to) ) {
 201+ global $wgUser;
189202 $out2 = '<table style="background: inherit;" width="100%" cellpadding="0" cellspacing="0" border="0">';
190203 $out2 .= '<tr valign="top"><td>' . $nsForm;
191 - $out2 .= '</td><td align="' . $align . '" style="font-size: smaller; margin-bottom: 1em;">';
192 - $out2 .= $morelinks . '</td></tr></table><hr />';
 204+ $out2 .= '</td><td align="' . $align . '" style="font-size: smaller; margin-bottom: 1em;">' .
 205+ $wgUser->getSkin()->makeKnownLink( $wgContLang->specialPage( "Allpages" ), wfMsgHtml ( 'allpages' ) );
 206+ $out2 .= "</td></tr></table><hr />";
193207 } else {
194208 $out2 = $nsForm . '<hr />';
195209 }
196210 }
197 -
198211 $wgOut->addHtml( $out2 . $out );
199212 }
200213
@@ -207,14 +220,14 @@
208221 $align = $wgContLang->isRtl() ? 'left' : 'right';
209222 $inpointf = htmlspecialchars( str_replace( '_', ' ', $inpoint ) );
210223 $outpointf = htmlspecialchars( str_replace( '_', ' ', $outpoint ) );
211 - $queryparams = ($namespace ? "namespace=$namespace" : '');
212 - $special = SpecialPage::getTitleFor( $this->name, $inpoint );
213 - $link = $special->escapeLocalUrl( $queryparams );
 224+ $queryparams = $namespace ? "namespace=$namespace&" : '';
 225+ $special = SpecialPage::getTitleFor( $this->name );
 226+ $link = $special->escapeLocalUrl( $queryparams . 'from=' . urlencode($inpoint) . '&to=' . urlencode($outpoint) );
214227
215228 $out = wfMsgHtml(
216229 'alphaindexline',
217 - "<a href=\"$link\">$inpointf</a></td><td><a href=\"$link\">",
218 - "</a></td><td><a href=\"$link\">$outpointf</a>"
 230+ "<a href=\"$link\">$inpointf</a></td><td>",
 231+ "</td><td><a href=\"$link\">$outpointf</a>"
219232 );
220233 return '<tr><td align="' . $align . '">'.$out.'</td></tr>';
221234 }
@@ -223,18 +236,20 @@
224237 * @param integer $namespace (Default NS_MAIN)
225238 * @param string $from list all pages from this name (default FALSE)
226239 */
227 -function showChunk( $namespace = NS_MAIN, $from, $including = false ) {
 240+function showChunk( $namespace = NS_MAIN, $from, $to, $including = false ) {
228241 global $wgOut, $wgUser, $wgContLang;
229242
230243 $sk = $wgUser->getSkin();
231244
232 - $fromList = $this->getNamespaceKeyAndText($namespace, $from);
 245+ $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
 246+ $toList = $this->getNamespaceKeyAndText( $namespace, $to );
 247+
233248 $namespaces = $wgContLang->getNamespaces();
234249 $align = $wgContLang->isRtl() ? 'left' : 'right';
235250
236251 $n = 0;
237252
238 - if ( !$fromList ) {
 253+ if ( !$fromList || !$toList ) {
239254 $out = wfMsgWikiHtml( 'allpagesbadtitle' );
240255 } elseif ( !in_array( $namespace, array_keys( $namespaces ) ) ) {
241256 // Show errormessage and reset to NS_MAIN
@@ -242,17 +257,19 @@
243258 $namespace = NS_MAIN;
244259 } else {
245260 list( $namespace, $fromKey, $from ) = $fromList;
 261+ list( $namespace, $toKey, $to ) = $toList;
246262
247263 $dbr = wfGetDB( DB_SLAVE );
248264 $res = $dbr->select( 'page',
249265 array( 'page_namespace', 'page_title', 'page_is_redirect' ),
250266 array(
251267 'page_namespace' => $namespace,
252 - 'page_title >= ' . $dbr->addQuotes( $fromKey )
 268+ 'page_title >= ' . $dbr->addQuotes( $fromKey ),
 269+ 'page_title <= ' . $dbr->addQuotes( $toKey ),
253270 ),
254271 __METHOD__,
255272 array(
256 - 'ORDER BY' => 'page_title',
 273+ 'ORDER BY' => 'page_title ASC',
257274 'LIMIT' => $this->maxPerPage + 1,
258275 'USE INDEX' => 'name_title',
259276 )
@@ -291,87 +308,15 @@
292309 if ( $including ) {
293310 $out2 = '';
294311 } else {
295 - if( $from == '' ) {
296 - // First chunk; no previous link.
297 - $prevTitle = null;
298 - } else {
299 - # Get the last title from previous chunk
300 - $dbr = wfGetDB( DB_SLAVE );
301 - $res_prev = $dbr->select(
302 - 'page',
303 - 'page_title',
304 - array( 'page_namespace' => $namespace, 'page_title < '.$dbr->addQuotes($from) ),
305 - __METHOD__,
306 - array( 'ORDER BY' => 'page_title DESC', 'LIMIT' => $this->maxPerPage, 'OFFSET' => ($this->maxPerPage - 1 ) )
307 - );
308 -
309 - # Get first title of previous complete chunk
310 - if( $dbr->numrows( $res_prev ) >= $this->maxPerPage ) {
311 - $pt = $dbr->fetchObject( $res_prev );
312 - $prevTitle = Title::makeTitle( $namespace, $pt->page_title );
313 - } else {
314 - # The previous chunk is not complete, need to link to the very first title
315 - # available in the database
316 - $options = array( 'LIMIT' => 1 );
317 - if ( ! $dbr->implicitOrderby() ) {
318 - $options['ORDER BY'] = 'page_title';
319 - }
320 - $reallyFirstPage_title = $dbr->selectField( 'page', 'page_title', array( 'page_namespace' => $namespace ), __METHOD__, $options );
321 - # Show the previous link if it s not the current requested chunk
322 - if( $from != $reallyFirstPage_title ) {
323 - $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
324 - } else {
325 - $prevTitle = null;
326 - }
327 - }
328 - }
329 -
330 - $nsForm = $this->namespaceForm( $namespace, $from );
 312+ $nsForm = $this->namespaceForm( $namespace, $from, $to );
331313 $out2 = '<table style="background: inherit;" width="100%" cellpadding="0" cellspacing="0" border="0">';
332314 $out2 .= '<tr valign="top"><td>' . $nsForm;
333315 $out2 .= '</td><td align="' . $align . '" style="font-size: smaller; margin-bottom: 1em;">' .
334 - $sk->makeKnownLink( $wgContLang->specialPage( "Allpages" ),
335 - wfMsgHtml ( 'allpages' ) );
336 -
337 - $self = SpecialPage::getTitleFor( 'Allpages' );
338 -
339 - # Do we put a previous link ?
340 - if( isset( $prevTitle ) && $pt = $prevTitle->getText() ) {
341 - $q = 'from=' . $prevTitle->getPartialUrl()
342 - . ( $namespace ? '&namespace=' . $namespace : '' );
343 - $prevLink = $sk->makeKnownLinkObj( $self,
344 - wfMsgHTML( 'prevpage', htmlspecialchars( $pt ) ), $q );
345 - $out2 .= ' | ' . $prevLink;
346 - }
347 -
348 - if( $n == $this->maxPerPage && $s = $dbr->fetchObject($res) ) {
349 - # $s is the first link of the next chunk
350 - $t = Title::MakeTitle($namespace, $s->page_title);
351 - $q = 'from=' . $t->getPartialUrl()
352 - . ( $namespace ? '&namespace=' . $namespace : '' );
353 - $nextLink = $sk->makeKnownLinkObj( $self,
354 - wfMsgHtml( 'nextpage', htmlspecialchars( $t->getText() ) ), $q );
355 - $out2 .= ' | ' . $nextLink;
356 - }
 316+ $sk->makeKnownLink( $wgContLang->specialPage( "Allpages" ), wfMsgHtml ( 'allpages' ) );
357317 $out2 .= "</td></tr></table><hr />";
358318 }
359319
360320 $wgOut->addHtml( $out2 . $out );
361 - if( isset($prevLink) or isset($nextLink) ) {
362 - $wgOut->addHtml( '<hr /><p style="font-size: smaller; float: ' . $align . '">' );
363 - if( isset( $prevLink ) ) {
364 - $wgOut->addHTML( $prevLink );
365 - }
366 - if( isset( $prevLink ) && isset( $nextLink ) ) {
367 - $wgOut->addHTML( ' | ' );
368 - }
369 - if( isset( $nextLink ) ) {
370 - $wgOut->addHTML( $nextLink );
371 - }
372 - $wgOut->addHTML( '</p>' );
373 -
374 - }
375 -
376321 }
377322
378323 /**
@@ -381,7 +326,7 @@
382327 * @static (sort of)
383328 * @access private
384329 */
385 -function getNamespaceKeyAndText ($ns, $text) {
 330+function getNamespaceKeyAndText( $ns, $text ) {
386331 if ( $text == '' )
387332 return array( $ns, '', '' ); # shortcut for common case
388333
@@ -401,4 +346,5 @@
402347 return NULL;
403348 }
404349 }
 350+
405351 }
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -2004,6 +2004,7 @@
20052005 'nextpage' => 'Next page ($1)',
20062006 'prevpage' => 'Previous page ($1)',
20072007 'allpagesfrom' => 'Display pages starting at:',
 2008+'allpagesto' => 'Display pages ending at:',
20082009 'allarticles' => 'All pages',
20092010 'allinnamespace' => 'All pages ($1 namespace)',
20102011 'allnotinnamespace' => 'All pages (not in $1 namespace)',

Follow-up revisions

RevisionCommit summaryAuthorDate
r39708Revert r39416, 39421, 39427, 39489, 39515, 39516 "Rewrite allpages to use a "...brion16:13, 20 August 2008

Status & tagging log