r32228 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r32227‎ | r32228 | r32229 >
Date:17:02, 20 March 2008
Author:simetrical
Status:old
Tags:
Comment:
Move some of the changes I made to Special:Categories out of SpecialCategories.php and into Pager.php. Allow multiple possible sort orders for IndexPager, allow user override of sort direction for IndexPager, add extra links as appropriate for AlphabeticPager. Some of this seems to duplicate TablePager logic; I'm not sure why that's a separate class to begin with. Or why AlphabeticPager is called that, given that it's not necessarily alphabetic at all. In fact all of these child classes seem to perform almost identical functions and it seems as though folding them into the IndexPager class would reduce code duplication.
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/Pager.php (modified) (history)
  • /trunk/phase3/includes/SpecialCategories.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
@@ -117,8 +117,6 @@
118118 'categoriespagetext',
119119 'special-categories-sort-count',
120120 'special-categories-sort-abc',
121 - 'special-categories-sort-asc',
122 - 'special-categories-sort-desc',
123121 'pagecategories',
124122 'pagecategorieslink',
125123 'category_header',
@@ -1135,6 +1133,8 @@
11361134 'notargettext',
11371135 'pager-newer-n',
11381136 'pager-older-n',
 1137+ 'pager-sort-asc',
 1138+ 'pager-sort-desc',
11391139 ),
11401140 'booksources' => array(
11411141 'booksources',
Index: trunk/phase3/includes/SpecialCategories.php
@@ -21,21 +21,6 @@
2222 * @addtogroup Pager
2323 */
2424 class CategoryPager extends AlphabeticPager {
25 - private $mOrderType = 'abc';
26 -
27 - public function __construct() {
28 - parent::__construct();
29 - if( $this->mRequest->getText( 'order' ) == 'count' ) {
30 - $this->mOrderType = 'count';
31 - }
32 - if( $this->mRequest->getText( 'direction' ) == 'asc' ) {
33 - $this->mDefaultDirection = false;
34 - } elseif( $this->mRequest->getText( 'direction' ) == 'desc'
35 - || $this->mOrderType == 'count' ) {
36 - $this->mDefaultDirection = true;
37 - }
38 - }
39 -
4025 function getQueryInfo() {
4126 global $wgRequest;
4227 return array(
@@ -46,14 +31,17 @@
4732 }
4833
4934 function getIndexField() {
50 - # We can't use mOrderType here, since this is called from the parent
51 - # constructor. Hmm.
52 - if( $this->mRequest->getText( 'order' ) == 'count' ) {
53 - return 'cat_pages';
54 - } else {
55 - return "cat_title";
56 - }
 35+ return array( 'abc' => 'cat_title', 'count' => 'cat_pages' );
5736 }
 37+
 38+ protected function getOrderTypeMessages() {
 39+ return array( 'abc' => 'special-categories-sort-abc',
 40+ 'count' => 'special-categories-sort-count' );
 41+ }
 42+
 43+ protected function getDefaultDirection() {
 44+ return array( 'abc' => false, 'count' => true );
 45+ }
5846
5947 /* Override getBody to apply LinksBatch on resultset before actually outputting anything. */
6048 public function getBody() {
@@ -80,39 +68,6 @@
8169 $wgLang->formatNum( $result->cat_pages ) );
8270 return Xml::tags('li', null, "$titleText ($count)" ) . "\n";
8371 }
84 -
85 - /** Override this to order by count */
86 - public function getNavigationBar() {
87 - $nav = parent::getNavigationBar() . ' (';
88 - if( $this->mOrderType == 'abc' ) {
89 - $nav .= $this->makeLink(
90 - wfMsgHTML( 'special-categories-sort-count' ),
91 - array( 'order' => 'count' )
92 - );
93 - } else {
94 - $nav .= $this->makeLink(
95 - wfMsgHTML( 'special-categories-sort-abc' ),
96 - array( 'order' => 'abc' )
97 - );
98 - }
99 - $nav .= ') (';
100 - # FIXME, these are stupid query names. "order" and "dir" are already
101 - # used.
102 - if( $this->mDefaultDirection ) {
103 - # Descending
104 - $nav .= $this->makeLink(
105 - wfMsgHTML( 'special-categories-sort-asc' ),
106 - array( 'direction' => 'asc' )
107 - );
108 - } else {
109 - $nav .= $this->makeLink(
110 - wfMsgHTML( 'special-categories-sort-desc' ),
111 - array( 'direction' => 'desc' )
112 - );
113 - }
114 - $nav .= ')';
115 - return $nav;
116 - }
11772 }
11873
11974
Index: trunk/phase3/includes/Pager.php
@@ -60,19 +60,34 @@
6161 public $mDb;
6262 public $mPastTheEndRow;
6363
 64+ /**
 65+ * The index to actually be used for ordering. This is a single string e-
 66+ * ven if multiple orderings are supported.
 67+ */
6468 protected $mIndexField;
65 -
 69+ /** For pages that support multiple types of ordering, which one to use. */
 70+ protected $mOrderType;
6671 /**
67 - * Default query direction. false for ascending, true for descending
 72+ * $mDefaultDirection gives the direction to use when sorting results:
 73+ * false for ascending, true for descending. If $mIsBackwards is set, we
 74+ * start from the opposite end, but we still sort the page itself according
 75+ * to $mDefaultDirection. E.g., if $mDefaultDirection is false but we're
 76+ * going backwards, we'll display the last page of results, but the last
 77+ * result will be at the bottom, not the top.
 78+ *
 79+ * "Default" is really a misnomer here, since now it's possible for the
 80+ * user to directly modify this with query parameters. TODO: rename that
 81+ * to $mDescending, maybe set this to that by reference for compatibility.
6882 */
69 - public $mDefaultDirection = false;
 83+ public $mDefaultDirection;
 84+ public $mIsBackwards;
7085
7186 /**
7287 * Result object for the query. Warning: seek before use.
7388 */
7489 public $mResult;
7590
76 - function __construct() {
 91+ public function __construct() {
7792 global $wgRequest, $wgUser;
7893 $this->mRequest = $wgRequest;
7994
@@ -80,14 +95,44 @@
8196 # arbitrary string to support the widest variety of index types. Be
8297 # careful outputting it into HTML!
8398 $this->mOffset = $this->mRequest->getText( 'offset' );
84 -
 99+
85100 # Use consistent behavior for the limit options
86101 $this->mDefaultLimit = intval( $wgUser->getOption( 'rclimit' ) );
87102 list( $this->mLimit, /* $offset */ ) = $this->mRequest->getLimitOffset();
88 -
 103+
89104 $this->mIsBackwards = ( $this->mRequest->getVal( 'dir' ) == 'prev' );
90 - $this->mIndexField = $this->getIndexField();
91105 $this->mDb = wfGetDB( DB_SLAVE );
 106+
 107+ $index = $this->getIndexField();
 108+ $order = $this->mRequest->getVal( 'order' );
 109+ if( is_array( $index ) && isset( $index[$order] ) ) {
 110+ $this->mOrderType = $order;
 111+ $this->mIndexField = $index[$order];
 112+ } elseif( is_array( $index ) ) {
 113+ # First element is the default
 114+ reset( $index );
 115+ list( $this->mOrderType, $this->mIndexField ) = each( $index );
 116+ } else {
 117+ # $index is not an array
 118+ $this->mOrderType = null;
 119+ $this->mIndexField = $index;
 120+ }
 121+
 122+ if( !isset( $this->mDefaultDirection ) ) {
 123+ $dir = $this->getDefaultDirection();
 124+ $this->mDefaultDirection = is_array( $dir )
 125+ ? $dir[$this->mOrderType]
 126+ : $dir;
 127+ }
 128+
 129+ # FIXME: Can we figure out a less confusing convention than using a
 130+ # "direction" parameter when we already have "dir" and "order"?
 131+ if( $this->mRequest->getVal( 'direction' ) == 'asc' ) {
 132+ $this->mDefaultDirection = false;
 133+ }
 134+ if( $this->mRequest->getVal( 'direction' ) == 'desc' ) {
 135+ $this->mDefaultDirection = true;
 136+ }
92137 }
93138
94139 /**
@@ -300,6 +345,8 @@
301346 unset( $this->mDefaultQuery['dir'] );
302347 unset( $this->mDefaultQuery['offset'] );
303348 unset( $this->mDefaultQuery['limit'] );
 349+ unset( $this->mDefaultQuery['direction'] );
 350+ unset( $this->mDefaultQuery['order'] );
304351 }
305352 return $this->mDefaultQuery;
306353 }
@@ -397,10 +444,32 @@
398445 abstract function getQueryInfo();
399446
400447 /**
401 - * This function should be overridden to return the name of the
402 - * index field.
 448+ * This function should be overridden to return the name of the index fi-
 449+ * eld. If the pager supports multiple orders, it may return an array of
 450+ * 'querykey' => 'indexfield' pairs, so that a request with &count=querykey
 451+ * will use indexfield to sort. In this case, the first returned key is
 452+ * the default.
403453 */
404454 abstract function getIndexField();
 455+
 456+ /**
 457+ * Return the default sorting direction: false for ascending, true for de-
 458+ * scending. You can also have an associative array of ordertype => dir,
 459+ * if multiple order types are supported. In this case getIndexField()
 460+ * must return an array, and the keys of that must exactly match the keys
 461+ * of this.
 462+ *
 463+ * For backward compatibility, this method's return value will be ignored
 464+ * if $this->mDefaultDirection is already set when the constructor is
 465+ * called, for instance if it's statically initialized. In that case the
 466+ * value of that variable (which must be a boolean) will be used.
 467+ *
 468+ * Note that despite its name, this does not return the value of the now-
 469+ * misnamed $this->mDefaultDirection member variable. That is not a
 470+ * default, it's the actual direction used. This is just the default and
 471+ * can be overridden by user input.
 472+ */
 473+ protected function getDefaultDirection() { return false; }
405474 }
406475
407476
@@ -409,8 +478,6 @@
410479 * @addtogroup Pager
411480 */
412481 abstract class AlphabeticPager extends IndexPager {
413 - public $mDefaultDirection = false;
414 -
415482 function __construct() {
416483 parent::__construct();
417484 }
@@ -422,20 +489,76 @@
423490 function getNavigationBar() {
424491 global $wgLang;
425492
 493+ if( isset( $this->mNavigationBar ) ) {
 494+ return $this->mNavigationBar;
 495+ }
 496+
426497 $linkTexts = array(
427498 'prev' => wfMsgHtml( 'prevn', $wgLang->formatNum( $this->mLimit ) ),
428499 'next' => wfMsgHtml( 'nextn', $wgLang->formatNum($this->mLimit ) ),
429 - 'first' => wfMsgHtml( 'page_first' ), /* Introduced the message */
430 - 'last' => wfMsgHtml( 'page_last' ) /* Introduced the message */
 500+ 'first' => wfMsgHtml( 'page_first' ),
 501+ 'last' => wfMsgHtml( 'page_last' )
431502 );
432503
433504 $pagingLinks = $this->getPagingLinks( $linkTexts );
434505 $limitLinks = $this->getLimitLinks();
435506 $limits = implode( ' | ', $limitLinks );
436507
437 - $this->mNavigationBar = "({$pagingLinks['first']} | {$pagingLinks['last']}) " . wfMsgHtml("viewprevnext", $pagingLinks['prev'], $pagingLinks['next'], $limits);
 508+ $this->mNavigationBar =
 509+ "({$pagingLinks['first']} | {$pagingLinks['last']}) " .
 510+ wfMsgHtml( 'viewprevnext', $pagingLinks['prev'],
 511+ $pagingLinks['next'], $limits );
 512+
 513+ # Which direction should the link go? Opposite of the current.
 514+ $dir = $this->mDefaultDirection ? 'asc' : 'desc';
 515+ $query = array( 'direction' => $dir );
 516+ if( $this->mOrderType !== null ) {
 517+ $query['order'] = $this->mOrderType;
 518+ }
 519+ # Note for grep: uses pager-sort-asc, pager-sort-desc
 520+ $this->mNavigationBar .= ' (' . $this->makeLink(
 521+ wfMsgHTML( "pager-sort-$dir" ),
 522+ $query
 523+ ) . ')';
 524+
 525+ if( !is_array( $this->getIndexField() ) ) {
 526+ # Early return to avoid undue nesting
 527+ return $this->mNavigationBar;
 528+ }
 529+
 530+ $extra = '';
 531+ $first = true;
 532+ $msgs = $this->getOrderTypeMessages();
 533+ foreach( array_keys( $msgs ) as $order ) {
 534+ if( $order == $this->mOrderType ) {
 535+ continue;
 536+ }
 537+ if( !$first ) {
 538+ $extra .= ' | ';
 539+ $first = false;
 540+ }
 541+ $extra .= $this->makeLink(
 542+ wfMsgHTML( $msgs[$order] ),
 543+ array( 'order' => $order )
 544+ );
 545+ }
 546+
 547+ if( $extra !== '' ) {
 548+ $this->mNavigationBar .= " ($extra)";
 549+ }
 550+
438551 return $this->mNavigationBar;
 552+ }
439553
 554+ /**
 555+ * If this supports multiple order type messages, give the message key for
 556+ * enabling each one in getNavigationBar. The return type is an associa-
 557+ * tive array whose keys must exactly match the keys of the array returned
 558+ * by getIndexField(), and whose values are message keys.
 559+ * @return array
 560+ */
 561+ protected function getOrderTypeMessages() {
 562+ return null;
440563 }
441564 }
442565
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -567,8 +567,6 @@
568568 'categoriespagetext' => 'The following categories contain pages or media.',
569569 'special-categories-sort-count' => 'sort by count',
570570 'special-categories-sort-abc' => 'sort alphabetically',
571 -'special-categories-sort-asc' => 'ascending',
572 -'special-categories-sort-desc' => 'descending',
573571 'pagecategories' => '{{PLURAL:$1|Category|Categories}}',
574572 'pagecategorieslink' => 'Special:Categories', # don't translate or duplicate this message to other languages
575573 'category_header' => 'Pages in category "$1"',
@@ -1731,6 +1729,8 @@
17321730 'notargettext' => 'You have not specified a target page or user to perform this function on.',
17331731 'pager-newer-n' => '{{PLURAL:$1|newer 1|newer $1}}',
17341732 'pager-older-n' => '{{PLURAL:$1|older 1|older $1}}',
 1733+'pager-sort-asc' => 'ascending',
 1734+'pager-sort-desc' => 'descending',
17351735
17361736 # Book sources
17371737 'booksources' => 'Book sources',
Index: trunk/phase3/RELEASE-NOTES
@@ -49,9 +49,11 @@
5050 * Add category table to allow better tracking of category membership counts
5151 ** (bug 1212) Give correct membership counts on the pages of large categories
5252 ** Use category table for more efficient display of Special:Categories
53 -** Allow sorting by number of members on Special:Categories, and also allow
54 - descending sorts
 53+** Allow sorting by number of members on Special:Categories
5554 * (bug 1459) Search for duplicate files by hash: Special:FileDuplicateSearch
 55+* Allow the user to choose whether to use a descending or ascending sort in
 56+ AlphabeticPager-based special pages (Categories, Listusers, Protectedpages/
 57+ titles).
5658
5759 === Bug fixes in 1.13 ===
5860

Status & tagging log