Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -30,10 +30,9 @@ |
31 | 31 | |
32 | 32 | == Changes since 1.9 == |
33 | 33 | |
34 | | -* (bug 5142) Fixed call of hook ArticleViewHeader |
35 | 34 | * (bug 7292) Fix site statistics when moving pages in/out of content namespaces |
36 | 35 | * (bug 6937) Introduce "statistics-footer" message, appended to Special:Statistics |
37 | | -* (bug 8531) Correct local name of Lingála (patch by Raymond) |
| 36 | +* (bug 8531) Correct local name of Lingála |
38 | 37 | * (bug 6638) List block flags in block log entries |
39 | 38 | * New script maintenance/language/checkExtensioni18n.php used to check i18n |
40 | 39 | progress in the extension repository. |
— | — | @@ -284,6 +283,10 @@ |
285 | 284 | Warning on upload of images with uppercase extension if image with lowercase |
286 | 285 | extension exists |
287 | 286 | * (bug 9363) Fix Postgres error on Recentchangeslinked |
| 287 | +* (bug 5142) Fixed call of hook ArticleViewHeader |
| 288 | +* (bug 4624) Namespace selection for Special:Whatlinkshere |
| 289 | + Scrolling backwards at Special:Whatlinkshere fixed |
| 290 | +* (bug 4777) Separate prev/next messages for Special:Whatlinkshere |
288 | 291 | |
289 | 292 | == Languages updated == |
290 | 293 | |
Index: trunk/phase3/languages/messages/MessagesDe.php |
— | — | @@ -1479,10 +1479,13 @@ |
1480 | 1480 | 'notargettitle' => 'Keine Seite angegeben', |
1481 | 1481 | 'notargettext' => 'Sie haben nicht angegeben, auf welche Seite diese Funktion angewendet werden soll.', |
1482 | 1482 | 'linklistsub' => '(Liste der Verweise)', |
1483 | | -'linkshere' => "Die folgenden Seiten verweisen auf '''[[:$1]]''':", |
1484 | | -'nolinkshere' => "Keine Seite verweist auf '''[[:$1]]'''.", |
| 1483 | +'linkshere' => "Die folgenden Seiten verweisen auf '''„[[:$1]]“''':", |
| 1484 | +'nolinkshere' => "Keine Seite verweist auf '''„[[:$1]]“'''.", |
| 1485 | +'nolinkshere-ns' => "Keine Seite verweist auf '''„[[:$1]]“''' im Namensraum „{{ns:$2}}“.", |
1485 | 1486 | 'isredirect' => 'Weiterleitungsseite', |
1486 | 1487 | 'istemplate' => 'Vorlageneinbindung', |
| 1488 | +'whatlinkshere-prev' => 'vorherige $1', |
| 1489 | +'whatlinkshere-next' => 'nächste $1', |
1487 | 1490 | |
1488 | 1491 | # Block/unblock |
1489 | 1492 | 'blockip' => 'IP-Adresse/Benutzer sperren', |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1897,17 +1897,20 @@ |
1898 | 1898 | |
1899 | 1899 | # What links here |
1900 | 1900 | # |
1901 | | -'whatlinkshere' => 'What links here', |
| 1901 | +'whatlinkshere' => 'What links here', |
1902 | 1902 | 'whatlinkshere-summary' => '', |
1903 | | -'whatlinkshere-barrow' => '<', |
1904 | | -'notargettitle' => 'No target', |
1905 | | -'notargettext' => 'You have not specified a target page or user |
| 1903 | +'whatlinkshere-barrow' => '<', |
| 1904 | +'notargettitle' => 'No target', |
| 1905 | +'notargettext' => 'You have not specified a target page or user |
1906 | 1906 | to perform this function on.', |
1907 | | -'linklistsub' => '(List of links)', |
1908 | | -'linkshere' => "The following pages link to '''[[:$1]]''':", |
1909 | | -'nolinkshere' => "No pages link to '''[[:$1]]'''.", |
1910 | | -'isredirect' => 'redirect page', |
1911 | | -'istemplate' => 'inclusion', |
| 1907 | +'linklistsub' => '(List of links)', |
| 1908 | +'linkshere' => "The following pages link to '''[[:$1]]''':", |
| 1909 | +'nolinkshere' => "No pages link to '''[[:$1]]'''.", |
| 1910 | +'nolinkshere-ns' => "No pages link to '''[[:$1]]''' at namespace {{ns:$2}}.", |
| 1911 | +'isredirect' => 'redirect page', |
| 1912 | +'istemplate' => 'inclusion', |
| 1913 | +'whatlinkshere-prev' => 'previous $1', |
| 1914 | +'whatlinkshere-next' => 'next $1', |
1912 | 1915 | |
1913 | 1916 | # Block/unblock IP |
1914 | 1917 | # |
Index: trunk/phase3/includes/SpecialWhatlinkshere.php |
— | — | @@ -16,7 +16,7 @@ |
17 | 17 | |
18 | 18 | class WhatLinksHerePage { |
19 | 19 | var $request, $par; |
20 | | - var $limit, $from, $dir, $target; |
| 20 | + var $limit, $from, $back, $target, $namespace; |
21 | 21 | var $selfTitle, $skin; |
22 | 22 | |
23 | 23 | function WhatLinksHerePage( &$request, $par = null ) { |
— | — | @@ -34,10 +34,7 @@ |
35 | 35 | $this->limit = 50; |
36 | 36 | } |
37 | 37 | $this->from = $this->request->getInt( 'from' ); |
38 | | - $this->dir = $this->request->getText( 'dir', 'next' ); |
39 | | - if ( $this->dir != 'prev' ) { |
40 | | - $this->dir = 'next'; |
41 | | - } |
| 38 | + $this->back = $this->request->getInt( 'back' ); |
42 | 39 | |
43 | 40 | $targetString = isset($this->par) ? $this->par : $this->request->getVal( 'target' ); |
44 | 41 | |
— | — | @@ -58,7 +55,7 @@ |
59 | 56 | |
60 | 57 | $wgOut->addHTML( wfMsg( 'whatlinkshere-barrow' ) . ' ' .$this->skin->makeLinkObj($this->target, '', 'redirect=no' )."<br />\n"); |
61 | 58 | |
62 | | - $this->showIndirectLinks( 0, $this->target, $this->limit, $this->from, $this->dir ); |
| 59 | + $this->showIndirectLinks( 0, $this->target, $this->limit, $this->from, $this->back ); |
63 | 60 | } |
64 | 61 | |
65 | 62 | /** |
— | — | @@ -66,20 +63,20 @@ |
67 | 64 | * @param Title $target Target title |
68 | 65 | * @param int $limit Number of entries to display |
69 | 66 | * @param Title $from Display from this article ID |
70 | | - * @param string $dir 'next' or 'prev', whether $fromTitle is the start or end of the list |
| 67 | + * @param Title $back Display from this article ID at backwards scrolling |
71 | 68 | * @private |
72 | 69 | */ |
73 | | - function showIndirectLinks( $level, $target, $limit, $from = 0, $dir = 'next' ) { |
| 70 | + function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) { |
74 | 71 | global $wgOut; |
75 | 72 | $fname = 'WhatLinksHerePage::showIndirectLinks'; |
76 | 73 | |
77 | 74 | $dbr = wfGetDB( DB_READ ); |
78 | 75 | |
79 | | - // Some extra validation |
80 | | - $from = intval( $from ); |
81 | | - if ( !$from && $dir == 'prev' ) { |
82 | | - // Before start? No make sense |
83 | | - $dir = 'next'; |
| 76 | + if ( ( $ns = $this->request->getVal( 'namespace', null )) !== null && $ns !== '' ) { |
| 77 | + $options['namespace'] = intval( $ns ); |
| 78 | + $this->setNamespace( $options['namespace'] ); |
| 79 | + } else { |
| 80 | + $options['namespace'] = ''; |
84 | 81 | } |
85 | 82 | |
86 | 83 | // Make the query |
— | — | @@ -95,14 +92,14 @@ |
96 | 93 | 'tl_title' => $target->getDBkey(), |
97 | 94 | ); |
98 | 95 | |
| 96 | + if ( $this->namespace !== null ){ |
| 97 | + $plConds['page_namespace'] = (int)$this->namespace; |
| 98 | + $tlConds['page_namespace'] = (int)$this->namespace; |
| 99 | + } |
| 100 | + |
99 | 101 | if ( $from ) { |
100 | | - if ( 'prev' == $dir ) { |
101 | | - $offsetCond = "page_id < $from"; |
102 | | - $options = array( 'ORDER BY page_id DESC' ); |
103 | | - } else { |
104 | | - $offsetCond = "page_id >= $from"; |
105 | | - $options = array( 'ORDER BY page_id' ); |
106 | | - } |
| 102 | + $offsetCond = "page_id >= $from"; |
| 103 | + $options = array( 'ORDER BY page_id' ); |
107 | 104 | } else { |
108 | 105 | $offsetCond = false; |
109 | 106 | $options = array( 'ORDER BY page_id,is_template DESC' ); |
— | — | @@ -120,14 +117,37 @@ |
121 | 118 | $plConds, $fname, $options ); |
122 | 119 | $tlRes = $dbr->select( array( 'templatelinks', 'page' ), $fields, |
123 | 120 | $tlConds, $fname, $options ); |
124 | | - |
125 | 121 | if ( !$dbr->numRows( $plRes ) && !$dbr->numRows( $tlRes ) ) { |
126 | | - if ( 0 == $level ) { |
| 122 | + if ( 0 == $level && !isset( $this->namespace ) ) { |
| 123 | + // really no links to here |
127 | 124 | $wgOut->addWikiText( wfMsg( 'nolinkshere', $this->target->getPrefixedText() ) ); |
| 125 | + } elseif ( 0 == $level && isset( $this->namespace ) ) { |
| 126 | + // no links from requested namespace to here |
| 127 | + $options = array(); // reinitialize for a further namespace search |
| 128 | + $options['namespace'] = $this->namespace; |
| 129 | + $options['target'] = $this->target->getPrefixedText(); |
| 130 | + list( $options['limit'], $options['offset']) = wfCheckLimits(); |
| 131 | + $wgOut->addHTML( $this->whatlinkshereForm( $options ) ); |
| 132 | + $wgOut->addWikiText( wfMsg( 'nolinkshere-ns', $this->target->getPrefixedText(), $this->namespace ) ); |
128 | 133 | } |
129 | 134 | return; |
130 | 135 | } |
131 | 136 | |
| 137 | + $options = array(); |
| 138 | + list( $options['limit'], $options['offset']) = wfCheckLimits(); |
| 139 | + if ( ( $ns = $this->request->getVal( 'namespace', null ) ) !== null && $ns !== '' && ctype_digit($ns) ) { |
| 140 | + $options['namespace'] = intval( $ns ); |
| 141 | + $this->setNamespace( $options['namespace'] ); |
| 142 | + } else { |
| 143 | + $options['namespace'] = ''; |
| 144 | + $this->setNamespace( null ); |
| 145 | + } |
| 146 | + $options['offset'] = $this->request->getVal( 'offset' ); |
| 147 | + /* Offset must be an integral. */ |
| 148 | + if ( !strlen( $options['offset'] ) || !preg_match( '/^[0-9]+$/', $options['offset'] ) ) |
| 149 | + $options['offset'] = ''; |
| 150 | + $options['target'] = $this->target->getPrefixedDBkey(); |
| 151 | + |
132 | 152 | // Read the rows into an array and remove duplicates |
133 | 153 | // templatelinks comes second so that the templatelinks row overwrites the |
134 | 154 | // pagelinks row, so we get (inclusion) rather than nothing |
— | — | @@ -149,46 +169,27 @@ |
150 | 170 | $numRows = count( $rows ); |
151 | 171 | |
152 | 172 | // Work out the start and end IDs, for prev/next links |
153 | | - if ( $dir == 'prev' ) { |
154 | | - // Descending order |
155 | | - if ( $numRows > $limit ) { |
156 | | - // More rows available before these ones |
157 | | - // Get the ID from the next row past the end of the displayed set |
158 | | - $prevId = $rows[$limit]->page_id; |
159 | | - // Remove undisplayed rows |
160 | | - $rows = array_slice( $rows, 0, $limit ); |
161 | | - } else { |
162 | | - // No more rows available before |
163 | | - $prevId = 0; |
164 | | - } |
165 | | - // Assume that the ID specified in $from exists, so there must be another page |
166 | | - $nextId = $from; |
167 | | - |
168 | | - // Reverse order ready for display |
169 | | - $rows = array_reverse( $rows ); |
| 173 | + if ( $numRows > $limit ) { |
| 174 | + // More rows available after these ones |
| 175 | + // Get the ID from the last row in the result set |
| 176 | + $nextId = $rows[$limit]->page_id; |
| 177 | + // Remove undisplayed rows |
| 178 | + $rows = array_slice( $rows, 0, $limit ); |
170 | 179 | } else { |
171 | | - // Ascending |
172 | | - if ( $numRows > $limit ) { |
173 | | - // More rows available after these ones |
174 | | - // Get the ID from the last row in the result set |
175 | | - $nextId = $rows[$limit]->page_id; |
176 | | - // Remove undisplayed rows |
177 | | - $rows = array_slice( $rows, 0, $limit ); |
178 | | - } else { |
179 | | - // No more rows after |
180 | | - $nextId = false; |
181 | | - } |
182 | | - $prevId = $from; |
| 180 | + // No more rows after |
| 181 | + $nextId = false; |
183 | 182 | } |
| 183 | + $prevId = $from; |
184 | 184 | |
185 | | - if ( 0 == $level ) { |
| 185 | + if ( $level == 0 ) { |
| 186 | + $wgOut->addHTML( $this->whatlinkshereForm( $options ) ); |
186 | 187 | $wgOut->addWikiText( wfMsg( 'linkshere', $this->target->getPrefixedText() ) ); |
187 | 188 | } |
188 | 189 | $isredir = wfMsg( 'isredirect' ); |
189 | 190 | $istemplate = wfMsg( 'istemplate' ); |
190 | 191 | |
191 | 192 | if( $level == 0 ) { |
192 | | - $prevnext = $this->getPrevNext( $limit, $prevId, $nextId ); |
| 193 | + $prevnext = $this->getPrevNext( $limit, $prevId, $nextId, $options['namespace'] ); |
193 | 194 | $wgOut->addHTML( $prevnext ); |
194 | 195 | } |
195 | 196 | |
— | — | @@ -236,19 +237,19 @@ |
237 | 238 | return $this->skin->makeKnownLinkObj( $this->selfTitle, $text, $query ); |
238 | 239 | } |
239 | 240 | |
240 | | - function getPrevNext( $limit, $prevId, $nextId ) { |
| 241 | + function getPrevNext( $limit, $prevId, $nextId, $namespace ) { |
241 | 242 | global $wgLang; |
242 | 243 | $fmtLimit = $wgLang->formatNum( $limit ); |
243 | | - $prev = wfMsg( 'prevn', $fmtLimit ); |
244 | | - $next = wfMsg( 'nextn', $fmtLimit ); |
| 244 | + $prev = wfMsg( 'whatlinkshere-prev', $fmtLimit ); |
| 245 | + $next = wfMsg( 'whatlinkshere-next', $fmtLimit ); |
245 | 246 | |
246 | 247 | if ( 0 != $prevId ) { |
247 | | - $prevLink = $this->makeSelfLink( $prev, "limit={$limit}&from={$prevId}&dir=prev" ); |
| 248 | + $prevLink = $this->makeSelfLink( $prev, "limit={$limit}&from={$this->back}&back={$fromId}&namespace={$namespace}" ); |
248 | 249 | } else { |
249 | 250 | $prevLink = $prev; |
250 | 251 | } |
251 | 252 | if ( 0 != $nextId ) { |
252 | | - $nextLink = $this->makeSelfLink( $next, "limit={$limit}&from={$nextId}" ); |
| 253 | + $nextLink = $this->makeSelfLink( $next, "limit={$limit}&from={$nextId}&back={$prevId}&namespace={$namespace}" ); |
253 | 254 | } else { |
254 | 255 | $nextLink = $next; |
255 | 256 | } |
— | — | @@ -267,6 +268,34 @@ |
268 | 269 | $fmtLimit = $wgLang->formatNum( $limit ); |
269 | 270 | return $this->makeSelfLink( $fmtLimit, $query ); |
270 | 271 | } |
| 272 | + |
| 273 | + function whatlinkshereForm( $options ) { |
| 274 | + global $wgScript, $wgTitle; |
| 275 | + |
| 276 | + $options['title'] = $wgTitle->getPrefixedText(); |
| 277 | + |
| 278 | + $f = Xml::openElement( 'form', array( 'method' => 'get', 'action' => "$wgScript" ) ) . |
| 279 | + '<fieldset>' . |
| 280 | + Xml::element( 'legend', array(), wfMsg( 'whatlinkshere' ) ); |
| 281 | + |
| 282 | + foreach ( $options as $name => $value ) { |
| 283 | + if( $name === 'namespace') continue; |
| 284 | + $f .= "\t" . Xml::hidden( $name, $value ). "\n"; |
| 285 | + } |
| 286 | + |
| 287 | + $f .= Xml::label( wfMsg( 'namespace' ), 'namespace' ) . ' ' . |
| 288 | + Xml::namespaceSelector( $options['namespace'], '' ) . |
| 289 | + Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . |
| 290 | + '</fieldset>' . |
| 291 | + Xml::closeElement( 'form' ) . "\n"; |
| 292 | + |
| 293 | + return $f; |
| 294 | + } |
| 295 | + |
| 296 | + function setNamespace( $ns ) { |
| 297 | + $this->namespace = $ns; |
| 298 | + } |
| 299 | + |
271 | 300 | } |
272 | 301 | |
273 | 302 | ?> |
Index: trunk/phase3/maintenance/language/messages.inc |
— | — | @@ -1233,8 +1233,11 @@ |
1234 | 1234 | 'linklistsub', |
1235 | 1235 | 'linkshere', |
1236 | 1236 | 'nolinkshere', |
| 1237 | + 'nolinkshere-ns', |
1237 | 1238 | 'isredirect', |
1238 | 1239 | 'istemplate', |
| 1240 | + 'whatlinkshere-prev', |
| 1241 | + 'whatlinkshere-next', |
1239 | 1242 | ), |
1240 | 1243 | 'block' => array( |
1241 | 1244 | 'blockip', |