r60746 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r60745‎ | r60746 | r60747 >
Date:20:35, 6 January 2010
Author:btongminh
Status:ok (Comments)
Tags:
Comment:
Fix prev links by either allowing a from= or to= parameter
Modified paths:
  • /trunk/extensions/GlobalUsage/GlobalUsageQuery.php (modified) (history)
  • /trunk/extensions/GlobalUsage/SpecialGlobalUsage.php (modified) (history)

Diff [purge]

Index: trunk/extensions/GlobalUsage/GlobalUsageQuery.php
@@ -5,11 +5,12 @@
66 */
77 class GlobalUsageQuery {
88 private $limit = 50;
9 - private $offset = 0;
 9+ private $offset;
1010 private $hasMore = false;
1111 private $filterLocal = false;
1212 private $result;
1313 private $continue;
 14+ private $reversed = false;
1415
1516 /**
1617 * @param $target mixed Title or db key, or array of db keys of target(s)
@@ -21,16 +22,20 @@
2223 $this->target = $target->getDBKey();
2324 else
2425 $this->target = $target;
25 - $this->offset = array( '', '', '' );
 26+ $this->offset = array();
2627
2728 }
2829
2930 /**
3031 * Set the offset parameter
3132 *
32 - * @param $offset int offset
 33+ * @param $offset string offset
 34+ * @param $reversed bool True if this is the upper offset
3335 */
34 - public function setOffset( $offset ) {
 36+ public function setOffset( $offset, $reversed = null ) {
 37+ if ( !is_null( $reversed ) )
 38+ $this->reversed = $reversed;
 39+
3540 if ( !is_array( $offset ) )
3641 $offset = explode( '|', $offset );
3742
@@ -50,12 +55,24 @@
5156 return implode( '|', $this->offset );
5257 }
5358 /**
 59+ * Is the result reversed
 60+ *
 61+ * @return bool
 62+ */
 63+ public function isReversed() {
 64+ return $this->reversed;
 65+ }
 66+ /**
5467 * Returns the string used for continuation
5568 *
5669 * @return string
 70+ *
5771 */
5872 public function getContinueString() {
59 - return "{$this->lastRow->gil_to}|{$this->lastRow->gil_wiki}|{$this->lastRow->gil_page}";
 73+ if ( $this->hasMore() )
 74+ return "{$this->lastRow->gil_to}|{$this->lastRow->gil_wiki}|{$this->lastRow->gil_page}";
 75+ else
 76+ return '';
6077 }
6178
6279 /**
@@ -85,21 +102,40 @@
86103 * Executes the query
87104 */
88105 public function execute() {
 106+ /* Construct a where clause */
 107+ // Add target image(s)
89108 $where = array( 'gil_to' => $this->target );
 109+
90110 if ( $this->filterLocal )
91111 // Don't show local file usage
92112 $where[] = 'gil_wiki != ' . $this->db->addQuotes( wfWikiId() );
93113
94114 // Set the continuation condition
95 - $qTo = $this->db->addQuotes( $this->offset[0] );
96 - $qWiki = $this->db->addQuotes( $this->offset[1] );
97 - $qPage = intval( $this->offset[2] );
 115+ $order = 'ASC';
 116+ if ( $this->offset ) {
 117+ $qTo = $this->db->addQuotes( $this->offset[0] );
 118+ $qWiki = $this->db->addQuotes( $this->offset[1] );
 119+ $qPage = intval( $this->offset[2] );
 120+
 121+ // Check which limit we got in order to determine which way to traverse rows
 122+ if ( $this->reversed ) {
 123+ // Reversed traversal; do not include offset row
 124+ $op1 = '<';
 125+ $op2 = '<';
 126+ $order = 'DESC';
 127+ } else {
 128+ // Normal traversal; include offset row
 129+ $op1 = '>';
 130+ $op2 = '>=';
 131+ $order = 'ASC';
 132+ }
 133+
 134+ $where[] = "(gil_to $op1 $qTo) OR " .
 135+ "(gil_to = $qTo AND gil_wiki $op1 $qWiki) OR " .
 136+ "(gil_to = $qTo AND gil_wiki = $qWiki AND gil_page $op2 $qPage)";
 137+ }
98138
99 - $where[] = "(gil_to > $qTo) OR " .
100 - "(gil_to = $qTo AND gil_wiki > $qWiki) OR " .
101 - "(gil_to = $qTo AND gil_wiki = $qWiki AND gil_page >= $qPage )";
102 -
103 -
 139+ /* Perform select (Duh.) */
104140 $res = $this->db->select( 'globalimagelinks',
105141 array(
106142 'gil_to',
@@ -111,16 +147,26 @@
112148 $where,
113149 __METHOD__,
114150 array(
115 - 'ORDER BY' => 'gil_to, gil_wiki, gil_page',
 151+ 'ORDER BY' => "gil_to $order, gil_wiki $order, gil_page $order",
116152 // Select an extra row to check whether we have more rows available
117153 'LIMIT' => $this->limit + 1,
118154 )
119155 );
120156
 157+ /* Process result */
 158+ // Always return the result in the same order; regardless whether reversed was specified
 159+ // reversed is really only used to determine from which direction the offset is
 160+ $rows = array();
 161+ foreach ( $res as $row )
 162+ $rows[] = $row;
 163+ if ( $this->reversed )
 164+ $rows = array_reverse( $rows );
 165+
 166+ // Build the result array
121167 $count = 0;
122168 $this->hasMore = false;
123169 $this->result = array();
124 - foreach ( $res as $row ) {
 170+ foreach ( $rows as $row ) {
125171 $count++;
126172 if ( $count > $this->limit ) {
127173 // We've reached the extra row that indicates that there are more rows
Index: trunk/extensions/GlobalUsage/SpecialGlobalUsage.php
@@ -85,7 +85,10 @@
8686 $query = new GlobalUsageQuery( $this->target );
8787
8888 // Extract params from $wgRequest
89 - $query->setOffset( $wgRequest->getText( 'offset' ) );
 89+ if ( $wgRequest->getText( 'from' ) )
 90+ $query->setOffset( $wgRequest->getText( 'from' ) );
 91+ elseif ( $wgRequest->getText( 'to' ) )
 92+ $query->setOffset( $wgRequest->getText( 'to' ), true );
9093 $query->setLimit( $wgRequest->getInt( 'limit', 50 ) );
9194 $query->filterLocal( $this->filterLocal );
9295
@@ -217,9 +220,17 @@
218221 $target = $this->target->getText();
219222 $limit = $query->getLimit();
220223 $fmtLimit = $wgLang->formatNum( $limit );
 224+
 225+ # Find out which strings are for the prev and which for the next links
221226 $offset = $query->getOffsetString();
222 - if ( $offset == '||' )
223 - $offset = '';
 227+ $continue = $query->getContinueString();
 228+ if ( $query->isReversed() ) {
 229+ $from = $offset;
 230+ $to = $continue;
 231+ } else {
 232+ $from = $continue;
 233+ $to = $offset;
 234+ }
224235
225236 # Get prev/next link display text
226237 $prev = wfMsgExt( 'prevn', array('parsemag','escape'), $fmtLimit );
@@ -232,18 +243,18 @@
233244 $title = $this->getTitle();
234245
235246 # Make 'previous' link
236 - if ( $offset ) {
 247+ if ( $to ) {
237248 $attr = array( 'title' => $pTitle, 'class' => 'mw-prevlink' );
238 - $q = array( 'limit' => $limit, 'offset' => $offset, 'target' => $target );
 249+ $q = array( 'limit' => $limit, 'to' => $to, 'target' => $target );
239250 $plink = $skin->link( $title, $prev, $attr, $q );
240251 } else {
241252 $plink = $prev;
242253 }
243254
244255 # Make 'next' link
245 - if ( $query->hasMore() ) {
 256+ if ( $from ) {
246257 $attr = array( 'title' => $nTitle, 'class' => 'mw-nextlink' );
247 - $q = array( 'limit' => $limit, 'offset' => $query->getContinueString(), 'target' => $target );
 258+ $q = array( 'limit' => $limit, 'from' => $from, 'target' => $target );
248259 $nlink = $skin->link( $title, $next, $attr, $q );
249260 } else {
250261 $nlink = $next;

Comments

#Comment by Tim Starling (talk | contribs)   07:57, 20 January 2010

We have IndexPager so that you don't have to do all this fiddling with from= and to= and array_reverse() and what not in order to implement paging. Is the only reason you're not using it the need to support ApiQueryGlobalUsage? If so, do we need to extend IndexPager to support API queries explicitly?

#Comment by Bryan (talk | contribs)   12:02, 20 January 2010

IndexPager does not seem to support paging for unique keys containing multiple columns, or it has been hidden very well.

I think indeed the proper solution would be to build a pager that 1) supports multiple multiple columns and 2) can be both used by the UI and the API. But that may be a bit of work.

Status & tagging log