r74205 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r74204‎ | r74205 | r74206 >
Date:14:37, 3 October 2010
Author:peter17
Status:ok (Comments)
Tags:
Comment:
GlobalUsage extension partially built-in, now named GlobalFileUsage and using the same GlobalUsageQuery as GlobalTemplateUsage
Modified paths:
  • /branches/iwtransclusion/phase3/includes/AutoLoader.php (modified) (history)
  • /branches/iwtransclusion/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/iwtransclusion/phase3/includes/GlobalUsageQuery.php (added) (history)
  • /branches/iwtransclusion/phase3/includes/SpecialPage.php (modified) (history)
  • /branches/iwtransclusion/phase3/includes/specials/SpecialGlobalFileUsage.php (added) (history)
  • /branches/iwtransclusion/phase3/includes/specials/SpecialGlobalTemplateUsage.php (modified) (history)
  • /branches/iwtransclusion/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: branches/iwtransclusion/phase3/languages/messages/MessagesEn.php
@@ -4330,6 +4330,18 @@
43314331 'compare-rev2' => 'Revision 2',
43324332 'compare-submit' => 'Compare',
43334333
 4334+# Special:GlobalFileUsage
 4335+'globalfileusage' => 'Global file usage',
 4336+'globalfileusage-for' => 'Global file usage for "$1"',
 4337+'globalfileusage-desc' => '[[Special:GlobalFileUsage|Special page]] to view global file usage',
 4338+'globalfileusage-ok' => 'Search',
 4339+'globalfileusage-text' => 'Search global file usage',
 4340+'globalfileusage-no-results' => '[[$1]] is not used on other wikis.',
 4341+'globalfileusage-on-wiki' => 'Usage on $2',
 4342+'globalfileusage-of-file' => 'The following other wikis use this file:',
 4343+'globalfileusage-more' => 'View [[{{#Special:GlobalUsage}}/$1|more global usage]] of this file.',
 4344+'globalfileusage-filterlocal' => 'Do not show local usage',
 4345+
43344346 # Special:GlobalTemplateUsage
43354347 'globaltemplateusage' => 'Global template usage',
43364348 'globaltemplateusage-for' => 'Global template usage for "$1"',
Index: branches/iwtransclusion/phase3/includes/GlobalUsageQuery.php
@@ -0,0 +1,351 @@
 2+<?php
 3+/**
 4+ * A helper class to query the globalimagelinks table
 5+ *
 6+ */
 7+class GlobalUsageQuery {
 8+ private $limit = 50;
 9+ private $offset;
 10+ private $hasMore = false;
 11+ private $filterLocal = false;
 12+ private $result;
 13+ private $continue;
 14+ private $reversed = false;
 15+ private $target = null;
 16+
 17+ /**
 18+ * @param $target mixed Title or db key, or array of db keys of target(s)
 19+ */
 20+ public function __construct( $target ) {
 21+ global $wgGlobalDatabase;
 22+ $this->db = wfGetDB( DB_SLAVE, array(), $wgGlobalDatabase );
 23+ if ( $target instanceof Title && $target->getNamespace( ) == NS_FILE )
 24+ $this->target = $target->getDBKey();
 25+ else
 26+ $this->target = $target;
 27+ $this->offset = array();
 28+
 29+ }
 30+
 31+ /**
 32+ * Set the offset parameter
 33+ *
 34+ * @param $offset string offset
 35+ * @param $reversed bool True if this is the upper offset
 36+ */
 37+ public function setOffset( $offset, $reversed = null ) {
 38+ if ( !is_null( $reversed ) )
 39+ $this->reversed = $reversed;
 40+
 41+ if ( !is_array( $offset ) )
 42+ $offset = explode( '|', $offset );
 43+
 44+ if ( count( $offset ) == 3 ) {
 45+ $this->offset = $offset;
 46+ return true;
 47+ } else {
 48+ return false;
 49+ }
 50+ }
 51+ /**
 52+ * Return the offset set by the user
 53+ *
 54+ * @return array offset
 55+ */
 56+ public function getOffsetString() {
 57+ return implode( '|', $this->offset );
 58+ }
 59+ /**
 60+ * Is the result reversed
 61+ *
 62+ * @return bool
 63+ */
 64+ public function isReversed() {
 65+ return $this->reversed;
 66+ }
 67+
 68+ /**
 69+ * Returns the string used for continuation in a file search
 70+ *
 71+ * @return string
 72+ *
 73+ */
 74+ public function getContinueFileString() {
 75+ if ( $this->hasMore() )
 76+ return "{$this->lastRow->gil_to}|{$this->lastRow->gil_wiki}|{$this->lastRow->gil_page}";
 77+ else
 78+ return '';
 79+ }
 80+
 81+ /**
 82+ * Returns the string used for continuation in a template search
 83+ *
 84+ * @return string
 85+ *
 86+ */
 87+ public function getContinueTemplateString() {
 88+ if ( $this->hasMore() )
 89+ return "{$this->lastRow->gtl_to_title}|{$this->lastRow->gtl_from_wiki}|{$this->lastRow->gtl_from_page}";
 90+ else
 91+ return '';
 92+ }
 93+
 94+ /**
 95+ * Set the maximum amount of items to return. Capped at 500.
 96+ *
 97+ * @param $limit int The limit
 98+ */
 99+ public function setLimit( $limit ) {
 100+ $this->limit = min( $limit, 500 );
 101+ }
 102+ /**
 103+ * Returns the user set limit
 104+ */
 105+ public function getLimit() {
 106+ return $this->limit;
 107+ }
 108+
 109+ /**
 110+ * Set whether to filter out the local usage
 111+ */
 112+ public function filterLocal( $value = true ) {
 113+ $this->filterLocal = $value;
 114+ }
 115+
 116+ /**
 117+ * Executes the query for a file search
 118+ */
 119+ public function searchTemplate() {
 120+ global $wgLocalInterwiki;
 121+
 122+ /* Construct a where clause */
 123+ // Add target template(s)
 124+ $where = array( 'gtl_to_prefix' => $wgLocalInterwiki,
 125+ 'gtl_to_namespace' => $this->target->getNamespace( ),
 126+ 'gtl_to_title' => $this->target->getDBkey( )
 127+ );
 128+
 129+ // Set the continuation condition
 130+ $order = 'ASC';
 131+ if ( $this->offset ) {
 132+ $qTo = $this->db->addQuotes( $this->offset[0] );
 133+ $qWiki = $this->db->addQuotes( $this->offset[1] );
 134+ $qPage = intval( $this->offset[2] );
 135+
 136+ // Check which limit we got in order to determine which way to traverse rows
 137+ if ( $this->reversed ) {
 138+ // Reversed traversal; do not include offset row
 139+ $op1 = '<';
 140+ $op2 = '<';
 141+ $order = 'DESC';
 142+ } else {
 143+ // Normal traversal; include offset row
 144+ $op1 = '>';
 145+ $op2 = '>=';
 146+ $order = 'ASC';
 147+ }
 148+
 149+ $where[] = "(gtl_to_title $op1 $qTo) OR " .
 150+ "(gtl_to_title = $qTo AND gtl_from_wiki $op1 $qWiki) OR " .
 151+ "(gtl_to_title = $qTo AND gtl_from_wiki = $qWiki AND gtl_from_page $op2 $qPage)";
 152+ }
 153+
 154+ /* Perform select (Duh.) */
 155+ $res = $this->db->select( 'globaltemplatelinks',
 156+ array(
 157+ 'gtl_to_title',
 158+ 'gtl_from_wiki',
 159+ 'gtl_from_page',
 160+ 'gtl_from_namespace',
 161+ 'gtl_from_title'
 162+ ),
 163+ $where,
 164+ __METHOD__,
 165+ array(
 166+ 'ORDER BY' => "gtl_to_title $order, gtl_from_wiki $order, gtl_from_page $order",
 167+ // Select an extra row to check whether we have more rows available
 168+ 'LIMIT' => $this->limit + 1,
 169+ )
 170+ );
 171+
 172+ /* Process result */
 173+ // Always return the result in the same order; regardless whether reversed was specified
 174+ // reversed is really only used to determine from which direction the offset is
 175+ $rows = array();
 176+ foreach ( $res as $row ) {
 177+ $rows[] = $row;
 178+ }
 179+ if ( $this->reversed ) {
 180+ $rows = array_reverse( $rows );
 181+ }
 182+
 183+ // Build the result array
 184+ $count = 0;
 185+ $this->hasMore = false;
 186+ $this->result = array();
 187+ foreach ( $rows as $row ) {
 188+ $count++;
 189+ if ( $count > $this->limit ) {
 190+ // We've reached the extra row that indicates that there are more rows
 191+ $this->hasMore = true;
 192+ $this->lastRow = $row;
 193+ break;
 194+ }
 195+
 196+ if ( !isset( $this->result[$row->gtl_to_title] ) ) {
 197+ $this->result[$row->gtl_to_title] = array();
 198+ }
 199+ if ( !isset( $this->result[$row->gtl_to_title][$row->gtl_from_wiki] ) ) {
 200+ $this->result[$row->gtl_to_title][$row->gtl_from_wiki] = array();
 201+ }
 202+
 203+ $this->result[$row->gtl_to_title][$row->gtl_from_wiki][] = array(
 204+ 'template' => $row->gtl_to_title,
 205+ 'id' => $row->gtl_from_page,
 206+ 'namespace' => $row->gtl_from_namespace,
 207+ 'title' => $row->gtl_from_title,
 208+ 'wiki' => $row->gtl_from_wiki,
 209+ );
 210+ }
 211+ }
 212+
 213+ /**
 214+ * Executes the query for a template search
 215+ */
 216+ public function searchFile() {
 217+ /* Construct a where clause */
 218+ // Add target image(s)
 219+ $where = array( 'gil_to' => $this->target );
 220+
 221+ if ( $this->filterLocal )
 222+ // Don't show local file usage
 223+ $where[] = 'gil_wiki != ' . $this->db->addQuotes( wfWikiId() );
 224+
 225+ // Set the continuation condition
 226+ $order = 'ASC';
 227+ if ( $this->offset ) {
 228+ $qTo = $this->db->addQuotes( $this->offset[0] );
 229+ $qWiki = $this->db->addQuotes( $this->offset[1] );
 230+ $qPage = intval( $this->offset[2] );
 231+
 232+ // Check which limit we got in order to determine which way to traverse rows
 233+ if ( $this->reversed ) {
 234+ // Reversed traversal; do not include offset row
 235+ $op1 = '<';
 236+ $op2 = '<';
 237+ $order = 'DESC';
 238+ } else {
 239+ // Normal traversal; include offset row
 240+ $op1 = '>';
 241+ $op2 = '>=';
 242+ $order = 'ASC';
 243+ }
 244+
 245+ $where[] = "(gil_to $op1 $qTo) OR " .
 246+ "(gil_to = $qTo AND gil_wiki $op1 $qWiki) OR " .
 247+ "(gil_to = $qTo AND gil_wiki = $qWiki AND gil_page $op2 $qPage)";
 248+ }
 249+
 250+ /* Perform select (Duh.) */
 251+ $res = $this->db->select( 'globalimagelinks',
 252+ array(
 253+ 'gil_to',
 254+ 'gil_wiki',
 255+ 'gil_page',
 256+ 'gil_page_namespace',
 257+ 'gil_page_title'
 258+ ),
 259+ $where,
 260+ __METHOD__,
 261+ array(
 262+ 'ORDER BY' => "gil_to $order, gil_wiki $order, gil_page $order",
 263+ // Select an extra row to check whether we have more rows available
 264+ 'LIMIT' => $this->limit + 1,
 265+ )
 266+ );
 267+
 268+ /* Process result */
 269+ // Always return the result in the same order; regardless whether reversed was specified
 270+ // reversed is really only used to determine from which direction the offset is
 271+ $rows = array();
 272+ foreach ( $res as $row )
 273+ $rows[] = $row;
 274+ if ( $this->reversed )
 275+ $rows = array_reverse( $rows );
 276+
 277+ // Build the result array
 278+ $count = 0;
 279+ $this->hasMore = false;
 280+ $this->result = array();
 281+ foreach ( $rows as $row ) {
 282+ $count++;
 283+ if ( $count > $this->limit ) {
 284+ // We've reached the extra row that indicates that there are more rows
 285+ $this->hasMore = true;
 286+ $this->lastRow = $row;
 287+ break;
 288+ }
 289+
 290+ if ( !isset( $this->result[$row->gil_to] ) )
 291+ $this->result[$row->gil_to] = array();
 292+ if ( !isset( $this->result[$row->gil_to][$row->gil_wiki] ) )
 293+ $this->result[$row->gil_to][$row->gil_wiki] = array();
 294+
 295+ $this->result[$row->gil_to][$row->gil_wiki][] = array(
 296+ 'image' => $row->gil_to,
 297+ 'id' => $row->gil_page,
 298+ 'namespace' => $row->gil_page_namespace,
 299+ 'title' => $row->gil_page_title,
 300+ 'wiki' => $row->gil_wiki,
 301+ );
 302+ }
 303+ }
 304+
 305+ /**
 306+ * Returns the result set. The result is a 4 dimensional array
 307+ * (file, wiki, page), whose items are arrays with keys:
 308+ * - image or template: File name or template name
 309+ * - id: Page id
 310+ * - namespace: Page namespace text
 311+ * - title: Unprefixed page title
 312+ * - wiki: Wiki id
 313+ *
 314+ * @return array Result set
 315+ */
 316+ public function getResult() {
 317+ return $this->result;
 318+ }
 319+ /**
 320+ * Returns a 3 dimensional array with the result of the first file. Useful
 321+ * if only one resource was queried.
 322+ *
 323+ * For further information see documentation of getResult()
 324+ *
 325+ * @return array Result set
 326+ */
 327+ public function getSingleResult() {
 328+ if ( $this->result ) {
 329+ return current( $this->result );
 330+ } else {
 331+ return array();
 332+ }
 333+ }
 334+
 335+ /**
 336+ * Returns whether there are more results
 337+ *
 338+ * @return bool
 339+ */
 340+ public function hasMore() {
 341+ return $this->hasMore;
 342+ }
 343+
 344+ /**
 345+ * Returns the result length
 346+ *
 347+ * @return int
 348+ */
 349+ public function count() {
 350+ return count( $this->result );
 351+ }
 352+}
Property changes on: branches/iwtransclusion/phase3/includes/GlobalUsageQuery.php
___________________________________________________________________
Added: svn:eol-style
1353 + native
Index: branches/iwtransclusion/phase3/includes/specials/SpecialGlobalTemplateUsage.php
@@ -71,7 +71,7 @@
7272 private function showResult() {
7373 global $wgRequest;
7474
75 - $query = new GlobalTemplateUsageQuery( $this->target );
 75+ $query = new GlobalUsageQuery( $this->target );
7676
7777 // Extract params from $wgRequest
7878 if ( $wgRequest->getText( 'from' ) ) {
@@ -82,7 +82,7 @@
8383 $query->setLimit( $wgRequest->getInt( 'limit', 50 ) );
8484
8585 // Perform query
86 - $query->execute();
 86+ $query->searchTemplate();
8787
8888 // Show result
8989 global $wgOut;
@@ -101,7 +101,7 @@
102102 $wgOut->addHtml( $navbar );
103103
104104 $wgOut->addHtml( '<div id="mw-globaltemplateusage-result">' );
105 - foreach ( $query->getSingleTemplateResult() as $wiki => $result ) {
 105+ foreach ( $query->getSingleResult() as $wiki => $result ) {
106106 $wgOut->addHtml(
107107 '<h2>' . wfMsgExt(
108108 'globaltemplateusage-on-wiki', 'parseinline',
@@ -151,7 +151,7 @@
152152
153153 # Find out which strings are for the prev and which for the next links
154154 $offset = $query->getOffsetString();
155 - $continue = $query->getContinueString();
 155+ $continue = $query->getContinueTemplateString();
156156 if ( $query->isReversed() ) {
157157 $from = $offset;
158158 $to = $continue;
@@ -205,244 +205,4 @@
206206 }
207207 }
208208
209 -/**
210 - * This class has been copied from Extension:GlobalUsage / GlobalUsageQuery.php
211 - * Extension:GlobalUsage should be built-in and the GlobalUsageQuery adapted
212 - * to be able to fetch the global usage of templates as well as files.
213 - *
214 - * @author Bryan Tong Minh <bryan.tongminh@gmail.com>
215 - * @author Peter Potrowl <peter017@gmail.com>
216 - */
217 -class GlobalTemplateUsageQuery {
218 - private $limit = 50;
219 - private $offset;
220 - private $hasMore = false;
221 - private $result;
222 - private $continue;
223 - private $reversed = false;
224 - private $target = null;
225209
226 - /**
227 - * @param $target mixed Title or db key, or array of db keys of target(s)
228 - */
229 - public function __construct( $target ) {
230 - global $wgGlobalDatabase;
231 - $this->db = wfGetDB( DB_SLAVE, array(), $wgGlobalDatabase );
232 - $this->target = $target;
233 - $this->offset = array();
234 - }
235 -
236 - /**
237 - * Set the offset parameter
238 - *
239 - * @param $offset string offset
240 - * @param $reversed bool True if this is the upper offset
241 - */
242 - public function setOffset( $offset, $reversed = null ) {
243 - if ( !is_null( $reversed ) ) {
244 - $this->reversed = $reversed;
245 - }
246 -
247 - if ( !is_array( $offset ) ) {
248 - $offset = explode( '|', $offset );
249 - }
250 -
251 - if ( count( $offset ) == 3 ) {
252 - $this->offset = $offset;
253 - return true;
254 - } else {
255 - return false;
256 - }
257 - }
258 - /**
259 - * Return the offset set by the user
260 - *
261 - * @return array offset
262 - */
263 - public function getOffsetString() {
264 - return implode( '|', $this->offset );
265 - }
266 -
267 - /**
268 - * Is the result reversed
269 - *
270 - * @return bool
271 - */
272 - public function isReversed() {
273 - return $this->reversed;
274 - }
275 -
276 - /**
277 - * Returns the string used for continuation
278 - *
279 - * @return string
280 - *
281 - */
282 - public function getContinueString() {
283 - if ( $this->hasMore() )
284 - return "{$this->lastRow->gtl_to_title}|{$this->lastRow->gtl_from_wiki}|{$this->lastRow->gtl_from_page}";
285 - else
286 - return '';
287 - }
288 -
289 - /**
290 - * Set the maximum amount of items to return. Capped at 500.
291 - *
292 - * @param $limit int The limit
293 - */
294 - public function setLimit( $limit ) {
295 - $this->limit = min( $limit, 500 );
296 - }
297 -
298 - /**
299 - * Returns the user set limit
300 - */
301 - public function getLimit() {
302 - return $this->limit;
303 - }
304 -
305 - /**
306 - * Executes the query
307 - */
308 - public function execute() {
309 - global $wgLocalInterwiki;
310 -
311 - /* Construct a where clause */
312 - // Add target template(s)
313 - $where = array( 'gtl_to_prefix' => $wgLocalInterwiki,
314 - 'gtl_to_namespace' => $this->target->getNamespace( ),
315 - 'gtl_to_title' => $this->target->getDBkey( )
316 - );
317 -
318 - // Set the continuation condition
319 - $order = 'ASC';
320 - if ( $this->offset ) {
321 - $qTo = $this->db->addQuotes( $this->offset[0] );
322 - $qWiki = $this->db->addQuotes( $this->offset[1] );
323 - $qPage = intval( $this->offset[2] );
324 -
325 - // Check which limit we got in order to determine which way to traverse rows
326 - if ( $this->reversed ) {
327 - // Reversed traversal; do not include offset row
328 - $op1 = '<';
329 - $op2 = '<';
330 - $order = 'DESC';
331 - } else {
332 - // Normal traversal; include offset row
333 - $op1 = '>';
334 - $op2 = '>=';
335 - $order = 'ASC';
336 - }
337 -
338 - $where[] = "(gtl_to_title $op1 $qTo) OR " .
339 - "(gtl_to_title = $qTo AND gtl_from_wiki $op1 $qWiki) OR " .
340 - "(gtl_to_title = $qTo AND gtl_from_wiki = $qWiki AND gtl_from_page $op2 $qPage)";
341 - }
342 -
343 - /* Perform select (Duh.) */
344 - $res = $this->db->select( 'globaltemplatelinks',
345 - array(
346 - 'gtl_to_title',
347 - 'gtl_from_wiki',
348 - 'gtl_from_page',
349 - 'gtl_from_namespace',
350 - 'gtl_from_title'
351 - ),
352 - $where,
353 - __METHOD__,
354 - array(
355 - 'ORDER BY' => "gtl_to_title $order, gtl_from_wiki $order, gtl_from_page $order",
356 - // Select an extra row to check whether we have more rows available
357 - 'LIMIT' => $this->limit + 1,
358 - )
359 - );
360 -
361 - /* Process result */
362 - // Always return the result in the same order; regardless whether reversed was specified
363 - // reversed is really only used to determine from which direction the offset is
364 - $rows = array();
365 - foreach ( $res as $row ) {
366 - $rows[] = $row;
367 - }
368 - if ( $this->reversed ) {
369 - $rows = array_reverse( $rows );
370 - }
371 -
372 - // Build the result array
373 - $count = 0;
374 - $this->hasMore = false;
375 - $this->result = array();
376 - foreach ( $rows as $row ) {
377 - $count++;
378 - if ( $count > $this->limit ) {
379 - // We've reached the extra row that indicates that there are more rows
380 - $this->hasMore = true;
381 - $this->lastRow = $row;
382 - break;
383 - }
384 -
385 - if ( !isset( $this->result[$row->gtl_to_title] ) ) {
386 - $this->result[$row->gtl_to_title] = array();
387 - }
388 - if ( !isset( $this->result[$row->gtl_to_title][$row->gtl_from_wiki] ) ) {
389 - $this->result[$row->gtl_to_title][$row->gtl_from_wiki] = array();
390 - }
391 -
392 - $this->result[$row->gtl_to_title][$row->gtl_from_wiki][] = array(
393 - 'template' => $row->gtl_to_title,
394 - 'id' => $row->gtl_from_page,
395 - 'namespace' => $row->gtl_from_namespace,
396 - 'title' => $row->gtl_from_title,
397 - 'wiki' => $row->gtl_from_wiki,
398 - );
399 - }
400 - }
401 - /**
402 - * Returns the result set. The result is a 4 dimensional array
403 - * (file, wiki, page), whose items are arrays with keys:
404 - * - template: File name
405 - * - id: Page id
406 - * - namespace: Page namespace text
407 - * - title: Unprefixed page title
408 - * - wiki: Wiki id
409 - *
410 - * @return array Result set
411 - */
412 - public function getResult() {
413 - return $this->result;
414 - }
415 -
416 - /**
417 - * Returns a 3 dimensional array with the result of the first file. Useful
418 - * if only one template was queried.
419 - *
420 - * For further information see documentation of getResult()
421 - *
422 - * @return array Result set
423 - */
424 - public function getSingleTemplateResult() {
425 - if ( $this->result ) {
426 - return current( $this->result );
427 - } else {
428 - return array();
429 - }
430 - }
431 -
432 - /**
433 - * Returns whether there are more results
434 - *
435 - * @return bool
436 - */
437 - public function hasMore() {
438 - return $this->hasMore;
439 - }
440 -
441 - /**
442 - * Returns the result length
443 - *
444 - * @return int
445 - */
446 - public function count() {
447 - return count( $this->result );
448 - }
449 -}
Index: branches/iwtransclusion/phase3/includes/specials/SpecialGlobalFileUsage.php
@@ -0,0 +1,224 @@
 2+<?php
 3+/**
 4+ * Special page to show global file usage. Also contains hook functions for
 5+ * showing usage on an image page.
 6+ */
 7+
 8+class SpecialGlobalFileUsage extends SpecialPage {
 9+ public function __construct() {
 10+ parent::__construct( 'GlobalFileUsage', 'globalfileusage' );
 11+
 12+ wfLoadExtensionMessages( 'globalfileusage' );
 13+ }
 14+
 15+ /**
 16+ * Entry point
 17+ */
 18+ public function execute( $par ) {
 19+ global $wgOut, $wgRequest;
 20+
 21+ $target = $par ? $par : $wgRequest->getVal( 'target' );
 22+ $this->target = Title::makeTitleSafe( NS_FILE, $target );
 23+
 24+ $this->filterLocal = $wgRequest->getCheck( 'filterlocal' );
 25+
 26+ $this->setHeaders();
 27+
 28+ $this->showForm();
 29+
 30+ if ( is_null( $this->target ) )
 31+ {
 32+ $wgOut->setPageTitle( wfMsg( 'globalfileusage' ) );
 33+ return;
 34+ }
 35+
 36+ $wgOut->setPageTitle( wfMsg( 'globalfileusage-for', $this->target->getPrefixedText() ) );
 37+
 38+ $this->showResult();
 39+ }
 40+
 41+ /**
 42+ * Shows the search form
 43+ */
 44+ private function showForm() {
 45+ global $wgScript, $wgOut, $wgRequest;
 46+
 47+ /* Build form */
 48+ $html = Xml::openElement( 'form', array( 'action' => $wgScript ) ) . "\n";
 49+ // Name of SpecialPage
 50+ $html .= Xml::hidden( 'title', $this->getTitle()->getPrefixedText() ) . "\n";
 51+ // Limit
 52+ $html .= Xml::hidden( 'limit', $wgRequest->getInt( 'limit', 50 ) );
 53+ // Input box with target prefilled if available
 54+ $formContent = "\t" . Xml::input( 'target', 40, is_null( $this->target ) ? ''
 55+ : $this->target->getText() )
 56+ // Submit button
 57+ . "\n\t" . Xml::element( 'input', array(
 58+ 'type' => 'submit',
 59+ 'value' => wfMsg( 'globalfileusage-ok' )
 60+ ) )
 61+ // Filter local checkbox
 62+ . "\n\t<p>" . Xml::checkLabel( wfMsg( 'globalfileusage-filterlocal' ),
 63+ 'filterlocal', 'mw-filterlocal', $this->filterLocal ) . '</p>';
 64+
 65+ if ( !is_null( $this->target ) && wfFindFile( $this->target ) ) {
 66+ // Show the image if it exists
 67+ global $wgUser, $wgContLang;
 68+ $skin = $wgUser->getSkin();
 69+
 70+ $html .= $skin->makeImageLinkObj( $this->target,
 71+ $this->target->getPrefixedText(),
 72+ /* $alt */ '', /* $align */ $wgContLang->alignEnd(),
 73+ /* $handlerParams */ array(), /* $framed */ false,
 74+ /* $thumb */ true );
 75+ }
 76+
 77+ // Wrap the entire form in a nice fieldset
 78+ $html .= Xml::fieldSet( wfMsg( 'globalfileusage-text' ), $formContent ) . "\n</form>";
 79+
 80+ $wgOut->addHtml( $html );
 81+ }
 82+
 83+ /**
 84+ * Creates as queryer and executes it based on $wgRequest
 85+ */
 86+ private function showResult() {
 87+ global $wgRequest;
 88+
 89+ $query = new GlobalUsageQuery( $this->target );
 90+
 91+ // Extract params from $wgRequest
 92+ if ( $wgRequest->getText( 'from' ) )
 93+ $query->setOffset( $wgRequest->getText( 'from' ) );
 94+ elseif ( $wgRequest->getText( 'to' ) )
 95+ $query->setOffset( $wgRequest->getText( 'to' ), true );
 96+ $query->setLimit( $wgRequest->getInt( 'limit', 50 ) );
 97+ $query->filterLocal( $this->filterLocal );
 98+
 99+ // Perform query
 100+ $query->searchFile();
 101+
 102+ // Show result
 103+ global $wgOut;
 104+
 105+ // Don't show form element if there is no data
 106+ if ( $query->count() == 0 ) {
 107+ $wgOut->addWikiMsg( 'globalfileusage-no-results', $this->target->getPrefixedText() );
 108+ return;
 109+ }
 110+
 111+ $offset = $query->getOffsetString();
 112+ $navbar = $this->getNavBar( $query );
 113+ $targetName = $this->target->getText();
 114+
 115+ // Top navbar
 116+ $wgOut->addHtml( $navbar );
 117+
 118+ $wgOut->addHtml( '<div id="mw-globalfileusage-result">' );
 119+ foreach ( $query->getSingleResult() as $wiki => $result ) {
 120+ $wgOut->addHtml(
 121+ '<h2>' . wfMsgExt(
 122+ 'globalfileusage-on-wiki', 'parseinline',
 123+ $targetName, WikiMap::getWikiName( $wiki ) )
 124+ . "</h2><ul>\n" );
 125+ foreach ( $result as $item )
 126+ $wgOut->addHtml( "\t<li>" . self::formatItem( $item ) . "</li>\n" );
 127+ $wgOut->addHtml( "</ul>\n" );
 128+ }
 129+ $wgOut->addHtml( '</div>' );
 130+
 131+ // Bottom navbar
 132+ $wgOut->addHtml( $navbar );
 133+ }
 134+ /**
 135+ * Helper to format a specific item
 136+ */
 137+ public static function formatItem( $item ) {
 138+ if ( !$item['namespace'] )
 139+ $page = $item['title'];
 140+ else
 141+ $page = "{$item['namespace']}:{$item['title']}";
 142+
 143+ $link = WikiMap::makeForeignLink( $item['wiki'], $page,
 144+ str_replace( '_', ' ', $page ) );
 145+ // Return only the title if no link can be constructed
 146+ return $link === false ? $page : $link;
 147+ }
 148+
 149+ /**
 150+ * Helper function to create the navbar, stolen from wfViewPrevNext
 151+ *
 152+ * @param $query GlobalUsageQuery An executed GlobalUsageQuery object
 153+ * @return string Navbar HTML
 154+ */
 155+ protected function getNavBar( $query ) {
 156+ global $wgLang, $wgUser;
 157+
 158+ $skin = $wgUser->getSkin();
 159+
 160+ $target = $this->target->getText();
 161+ $limit = $query->getLimit();
 162+ $fmtLimit = $wgLang->formatNum( $limit );
 163+
 164+ # Find out which strings are for the prev and which for the next links
 165+ $offset = $query->getOffsetString();
 166+ $continue = $query->getContinueFileString();
 167+ if ( $query->isReversed() ) {
 168+ $from = $offset;
 169+ $to = $continue;
 170+ } else {
 171+ $from = $continue;
 172+ $to = $offset;
 173+ }
 174+
 175+ # Get prev/next link display text
 176+ $prev = wfMsgExt( 'prevn', array( 'parsemag', 'escape' ), $fmtLimit );
 177+ $next = wfMsgExt( 'nextn', array( 'parsemag', 'escape' ), $fmtLimit );
 178+ # Get prev/next link title text
 179+ $pTitle = wfMsgExt( 'prevn-title', array( 'parsemag', 'escape' ), $fmtLimit );
 180+ $nTitle = wfMsgExt( 'nextn-title', array( 'parsemag', 'escape' ), $fmtLimit );
 181+
 182+ # Fetch the title object
 183+ $title = $this->getTitle();
 184+
 185+ # Make 'previous' link
 186+ if ( $to ) {
 187+ $attr = array( 'title' => $pTitle, 'class' => 'mw-prevlink' );
 188+ $q = array( 'limit' => $limit, 'to' => $to, 'target' => $target );
 189+ if ( $this->filterLocal )
 190+ $q['filterlocal'] = '1';
 191+ $plink = $skin->link( $title, $prev, $attr, $q );
 192+ } else {
 193+ $plink = $prev;
 194+ }
 195+
 196+ # Make 'next' link
 197+ if ( $from ) {
 198+ $attr = array( 'title' => $nTitle, 'class' => 'mw-nextlink' );
 199+ $q = array( 'limit' => $limit, 'from' => $from, 'target' => $target );
 200+ if ( $this->filterLocal )
 201+ $q['filterlocal'] = '1';
 202+ $nlink = $skin->link( $title, $next, $attr, $q );
 203+ } else {
 204+ $nlink = $next;
 205+ }
 206+
 207+ # Make links to set number of items per page
 208+ $numLinks = array();
 209+ foreach ( array( 20, 50, 100, 250, 500 ) as $num ) {
 210+ $fmtLimit = $wgLang->formatNum( $num );
 211+
 212+ $q = array( 'offset' => $offset, 'limit' => $num, 'target' => $target );
 213+ if ( $this->filterLocal )
 214+ $q['filterlocal'] = '1';
 215+ $lTitle = wfMsgExt( 'shown-title', array( 'parsemag', 'escape' ), $num );
 216+ $attr = array( 'title' => $lTitle, 'class' => 'mw-numlink' );
 217+
 218+ $numLinks[] = $skin->link( $title, $fmtLimit, $attr, $q );
 219+ }
 220+ $nums = $wgLang->pipeList( $numLinks );
 221+
 222+ return wfMsgHtml( 'viewprevnext', $plink, $nlink, $nums );
 223+ }
 224+}
 225+
Property changes on: branches/iwtransclusion/phase3/includes/specials/SpecialGlobalFileUsage.php
___________________________________________________________________
Added: svn:eol-style
1226 + native
Index: branches/iwtransclusion/phase3/includes/DefaultSettings.php
@@ -4727,6 +4727,7 @@
47284728 'Export' => 'pagetools',
47294729 'Import' => 'pagetools',
47304730 'Whatlinkshere' => 'pagetools',
 4731+ 'GlobalFileUsage' => 'pagetools',
47314732 'GlobalTemplateUsage' => 'pagetools',
47324733
47334734 'Statistics' => 'wiki',
Index: branches/iwtransclusion/phase3/includes/AutoLoader.php
@@ -98,6 +98,7 @@
9999 'FormatExif' => 'includes/Exif.php',
100100 'FormOptions' => 'includes/FormOptions.php',
101101 'GlobalDependency' => 'includes/CacheDependency.php',
 102+ 'GlobalUsageQuery' => 'includes/GlobalUsageQuery.php',
102103 'HashBagOStuff' => 'includes/BagOStuff.php',
103104 'HashtableReplacer' => 'includes/StringUtils.php',
104105 'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
@@ -619,6 +620,7 @@
620621 'SpecialComparePages' => 'includes/specials/SpecialComparePages.php',
621622 'SpecialExport' => 'includes/specials/SpecialExport.php',
622623 'SpecialFilepath' => 'includes/specials/SpecialFilepath.php',
 624+ 'SpecialGlobalFileUsage' => 'includes/specials/SpecialGlobalFileUsage.php',
623625 'SpecialGlobalTemplateUsage' => 'includes/specials/SpecialGlobalTemplateUsage.php',
624626 'SpecialImport' => 'includes/specials/SpecialImport.php',
625627 'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
Index: branches/iwtransclusion/phase3/includes/SpecialPage.php
@@ -173,6 +173,7 @@
174174 # Page tools
175175 'ComparePages' => 'SpecialComparePages',
176176 'Export' => 'SpecialExport',
 177+ 'GlobalFileUsage' => 'SpecialGlobalFileUsage',
177178 'GlobalTemplateUsage' => 'SpecialGlobalTemplateUsage',
178179 'Import' => 'SpecialImport',
179180 'Undelete' => 'UndeleteForm',

Follow-up revisions

RevisionCommit summaryAuthorDate
r74210Merging with trunk r74205peter1715:02, 3 October 2010
r87112Merge r74205reedy00:58, 29 April 2011
r92997Merge r87112, merge of r74205reedy18:34, 24 July 2011

Comments

#Comment by Nikerabbit (talk | contribs)   16:14, 3 October 2010
+'globalfileusage-on-wiki' => 'Usage on $2',

Needs documentation for translators.

The special page should have an alias defined in MessagesEn.php

I sense some code duplication in searchTemplate and searchFile.

The code should use many more braces according to coding conventions.

+		wfLoadExtensionMessages( 'globalfileusage' );

Left-over from merge?

+		if ( is_null( $this->target ) )
+		{

Should be on one line.

#Comment by Peter17 (talk | contribs)   06:12, 4 October 2010

Please see r74246

Documentation for translators: done

I think the aliases for the special pages are

  • 'globalfileusage' => 'Global file usage',
  • 'globaltemplateusage' => 'Global template usage',

I don't see anything else for the other special pages... Can you give more precisions, please?

There is actually code duplication in searchTemplate and searchFile, but it is mainly due to different DB keys: 'gtl_to_title', 'gtl_from_wiki', etc. vs. 'gil_wiki', 'gil_page_title', etc. Maybe it can be improved, but until now, all the file was duplicated, so, this version has less code duplication than the previous one...

The original code of GlobalUsage has very few brackets. I have added a lot. I made a second pass; I hope it is ok, but some might still be missing...

wfLoadExtensionMessages left-over from merge: yes ;)

Should be online: done

#Comment by Nikerabbit (talk | contribs)   06:24, 4 October 2010

Sorry I was not explicit enough. Core special pages should have an entry in $specialPageAliases in MessagesEn.php, with the primary name/alias.

#Comment by Peter17 (talk | contribs)   15:12, 15 October 2010

Done in r74805.

Status & tagging log