r92996 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r92995‎ | r92996 | r92997 >
Date:18:31, 24 July 2011
Author:reedy
Status:deferred
Tags:
Comment:
Merge r87111, which is a merge of r70966, r71049

Get a conflict with the changes in r83512 in Title, have attempted to work out what seems best, but might want extra review there...
Modified paths:
  • /branches/iwtransclusion/phase3v3/includes/AutoLoader.php (modified) (history)
  • /branches/iwtransclusion/phase3v3/includes/DefaultSettings.php (modified) (history)
  • /branches/iwtransclusion/phase3v3/includes/SpecialPageFactory.php (modified) (history)
  • /branches/iwtransclusion/phase3v3/includes/Title.php (modified) (history)
  • /branches/iwtransclusion/phase3v3/includes/parser/Parser.php (modified) (history)
  • /branches/iwtransclusion/phase3v3/includes/specials/SpecialGlobalTemplateUsage.php (added) (history)
  • /branches/iwtransclusion/phase3v3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: branches/iwtransclusion/phase3v3/includes/SpecialPageFactory.php
@@ -126,6 +126,7 @@
127127 // Page tools
128128 'ComparePages' => 'SpecialComparePages',
129129 'Export' => 'SpecialExport',
 130+ 'GlobalTemplateUsage' => 'SpecialGlobalTemplateUsage',
130131 'Import' => 'SpecialImport',
131132 'Undelete' => 'SpecialUndelete',
132133 'Whatlinkshere' => 'SpecialWhatlinkshere',
Property changes on: branches/iwtransclusion/phase3v3/includes/SpecialPageFactory.php
___________________________________________________________________
Modified: svn:mergeinfo
133134 Merged /branches/iwtransclusion/phase3v2/includes/SpecialPageFactory.php:r87111
134135 Merged /branches/iwtransclusion/phase3/includes/SpecialPageFactory.php:r70966,71049
Index: branches/iwtransclusion/phase3v3/includes/parser/Parser.php
@@ -3267,7 +3267,6 @@
32683268 $found = true;
32693269 }
32703270 } elseif ( $wgEnableInterwikiTranscluding && $title->isTrans() ) {
3271 - // TODO: Work by Peter17 in progress
32723271
32733272 $text = Interwiki::interwikiTransclude( $title );
32743273 $this->registerDistantTemplate( $title );
Index: branches/iwtransclusion/phase3v3/includes/AutoLoader.php
@@ -751,6 +751,7 @@
752752 'SpecialEmailUser' => 'includes/specials/SpecialEmailuser.php',
753753 'SpecialExport' => 'includes/specials/SpecialExport.php',
754754 'SpecialFilepath' => 'includes/specials/SpecialFilepath.php',
 755+ 'SpecialGlobalTemplateUsage' => 'includes/specials/SpecialGlobalTemplateUsage.php',
755756 'SpecialImport' => 'includes/specials/SpecialImport.php',
756757 'SpecialListFiles' => 'includes/specials/SpecialListfiles.php',
757758 'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
Property changes on: branches/iwtransclusion/phase3v3/includes/AutoLoader.php
___________________________________________________________________
Modified: svn:mergeinfo
758759 Merged /branches/iwtransclusion/phase3/includes/AutoLoader.php:r70966,71049
759760 Merged /branches/iwtransclusion/phase3v2/includes/AutoLoader.php:r87111
Index: branches/iwtransclusion/phase3v3/includes/Title.php
@@ -1026,8 +1026,13 @@
10271027 * @return String the URL
10281028 */
10291029 public function getInternalURL( $query = '', $variant = false ) {
1030 - global $wgInternalServer, $wgServer;
1031 - $server = $wgInternalServer !== false ? $wgInternalServer : $wgServer;
 1030+ if ( $this->isExternal( ) ) {
 1031+ $server = '';
 1032+ } else {
 1033+ global $wgInternalServer, $wgServer;
 1034+ $server = $wgInternalServer !== false ? $wgInternalServer : $wgServer;
 1035+ }
 1036+
10321037 $url = $server . $this->getLocalURL( $query, $variant );
10331038 wfRunHooks( 'GetInternalURL', array( &$this, &$url, $query ) );
10341039 return $url;
Property changes on: branches/iwtransclusion/phase3v3/includes/Title.php
___________________________________________________________________
Modified: svn:mergeinfo
10351040 Merged /branches/iwtransclusion/phase3v2/includes/Title.php:r87111
10361041 Merged /branches/iwtransclusion/phase3/includes/Title.php:r70966,71049
Index: branches/iwtransclusion/phase3v3/includes/DefaultSettings.php
@@ -5085,6 +5085,7 @@
50865086 'Export' => 'pagetools',
50875087 'Import' => 'pagetools',
50885088 'Whatlinkshere' => 'pagetools',
 5089+ 'GlobalTemplateUsage' => 'pagetools',
50895090
50905091 'Statistics' => 'wiki',
50915092 'Version' => 'wiki',
Index: branches/iwtransclusion/phase3v3/includes/specials/SpecialGlobalTemplateUsage.php
@@ -0,0 +1,448 @@
 2+<?php
 3+/**
 4+ * This file has been copied from Extension:GlobalUsage and adapted
 5+ * to show the usage of a template instead of a file.
 6+ * Special page to show global template usage. Also contains hook functions for
 7+ * showing usage on an template page.
 8+ *
 9+ * @author Bryan Tong Minh <bryan.tongminh@gmail.com>
 10+ * @author Peter Potrowl <peter017@gmail.com>
 11+ */
 12+
 13+class SpecialGlobalTemplateUsage extends SpecialPage {
 14+ public function __construct() {
 15+ parent::__construct( 'GlobalTemplateUsage' );
 16+ }
 17+
 18+ /**
 19+ * Entry point
 20+ */
 21+ public function execute( $par ) {
 22+ global $wgOut, $wgRequest;
 23+
 24+ $target = $par ? $par : $wgRequest->getVal( 'target' );
 25+ $this->target = Title::newFromText( $target );
 26+
 27+ $this->setHeaders();
 28+
 29+ $this->showForm();
 30+
 31+ if ( is_null( $this->target ) )
 32+ {
 33+ $wgOut->setPageTitle( wfMsg( 'globaltemplateusage' ) );
 34+ return;
 35+ }
 36+
 37+ $wgOut->setPageTitle( wfMsg( 'globaltemplateusage-for', $this->target->getPrefixedText() ) );
 38+
 39+ $this->showResult();
 40+ }
 41+
 42+ /**
 43+ * Shows the search form
 44+ */
 45+ private function showForm() {
 46+ global $wgScript, $wgOut, $wgRequest;
 47+
 48+ /* Build form */
 49+ $html = Xml::openElement( 'form', array( 'action' => $wgScript ) ) . "\n";
 50+ // Name of SpecialPage
 51+ $html .= Xml::hidden( 'title', $this->getTitle( )->getPrefixedText( ) ) . "\n";
 52+ // Limit
 53+ $html .= Xml::hidden( 'limit', $wgRequest->getInt( 'limit', 50 ) );
 54+ // Input box with target prefilled if available
 55+ $formContent = "\t" . Xml::input( 'target', 40, is_null( $this->target ) ? ''
 56+ : $this->target->getPrefixedText( ) )
 57+ // Submit button
 58+ . "\n\t" . Xml::element( 'input', array(
 59+ 'type' => 'submit',
 60+ 'value' => wfMsg( 'globaltemplateusage-ok' )
 61+ ) );
 62+
 63+ // Wrap the entire form in a nice fieldset
 64+ $html .= Xml::fieldSet( wfMsg( 'globaltemplateusage-text' ), $formContent ) . "\n</form>";
 65+
 66+ $wgOut->addHtml( $html );
 67+ }
 68+
 69+ /**
 70+ * Creates as queryer and executes it based on $wgRequest
 71+ */
 72+ private function showResult() {
 73+ global $wgRequest;
 74+
 75+ $query = new GlobalTemplateUsageQuery( $this->target );
 76+
 77+ // Extract params from $wgRequest
 78+ if ( $wgRequest->getText( 'from' ) ) {
 79+ $query->setOffset( $wgRequest->getText( 'from' ) );
 80+ } elseif ( $wgRequest->getText( 'to' ) ) {
 81+ $query->setOffset( $wgRequest->getText( 'to' ), true );
 82+ }
 83+ $query->setLimit( $wgRequest->getInt( 'limit', 50 ) );
 84+
 85+ // Perform query
 86+ $query->execute();
 87+
 88+ // Show result
 89+ global $wgOut;
 90+
 91+ // Don't show form element if there is no data
 92+ if ( $query->count() == 0 ) {
 93+ $wgOut->addWikiMsg( 'globaltemplateusage-no-results', $this->target->getPrefixedText( ) );
 94+ return;
 95+ }
 96+
 97+ $offset = $query->getOffsetString( );
 98+ $navbar = $this->getNavBar( $query );
 99+ $targetName = $this->target->getPrefixedText( );
 100+
 101+ // Top navbar
 102+ $wgOut->addHtml( $navbar );
 103+
 104+ $wgOut->addHtml( '<div id="mw-globaltemplateusage-result">' );
 105+ foreach ( $query->getSingleTemplateResult() as $wiki => $result ) {
 106+ $wgOut->addHtml(
 107+ '<h2>' . wfMsgExt(
 108+ 'globaltemplateusage-on-wiki', 'parseinline',
 109+ $targetName, WikiMap::getWikiName( $wiki ) )
 110+ . "</h2><ul>\n" );
 111+ foreach ( $result as $item ) {
 112+ $wgOut->addHtml( "\t<li>" . self::formatItem( $item ) . "</li>\n" );
 113+ }
 114+ $wgOut->addHtml( "</ul>\n" );
 115+ }
 116+ $wgOut->addHtml( '</div>' );
 117+
 118+ // Bottom navbar
 119+ $wgOut->addHtml( $navbar );
 120+ }
 121+
 122+ /**
 123+ * Helper to format a specific item
 124+ */
 125+ public static function formatItem( $item ) {
 126+ if ( !$item['namespace'] ) {
 127+ $page = $item['title'];
 128+ } else {
 129+ $page = "{$item['namespace']}:{$item['title']}";
 130+ }
 131+
 132+ $link = WikiMap::makeForeignLink( $item['wiki'], $page,
 133+ str_replace( '_', ' ', $page ) );
 134+ // Return only the title if no link can be constructed
 135+ return $link === false ? $page : $link;
 136+ }
 137+
 138+ /**
 139+ * Helper function to create the navbar, stolen from wfViewPrevNext
 140+ *
 141+ * @param $query GlobalTemplateUsageQuery An executed GlobalTemplateUsageQuery object
 142+ * @return string Navbar HTML
 143+ */
 144+ protected function getNavBar( $query ) {
 145+ global $wgLang, $wgUser;
 146+
 147+ $skin = $wgUser->getSkin();
 148+
 149+ $target = $this->target->getPrefixedText();
 150+ $limit = $query->getLimit();
 151+ $fmtLimit = $wgLang->formatNum( $limit );
 152+
 153+ # Find out which strings are for the prev and which for the next links
 154+ $offset = $query->getOffsetString();
 155+ $continue = $query->getContinueString();
 156+ if ( $query->isReversed() ) {
 157+ $from = $offset;
 158+ $to = $continue;
 159+ } else {
 160+ $from = $continue;
 161+ $to = $offset;
 162+ }
 163+
 164+ # Get prev/next link display text
 165+ $prev = wfMsgExt( 'prevn', array( 'parsemag', 'escape' ), $fmtLimit );
 166+ $next = wfMsgExt( 'nextn', array( 'parsemag', 'escape' ), $fmtLimit );
 167+ # Get prev/next link title text
 168+ $pTitle = wfMsgExt( 'prevn-title', array( 'parsemag', 'escape' ), $fmtLimit );
 169+ $nTitle = wfMsgExt( 'nextn-title', array( 'parsemag', 'escape' ), $fmtLimit );
 170+
 171+ # Fetch the title object
 172+ $title = $this->getTitle();
 173+
 174+ # Make 'previous' link
 175+ if ( $to ) {
 176+ $attr = array( 'title' => $pTitle, 'class' => 'mw-prevlink' );
 177+ $q = array( 'limit' => $limit, 'to' => $to, 'target' => $target );
 178+ $plink = $skin->link( $title, $prev, $attr, $q );
 179+ } else {
 180+ $plink = $prev;
 181+ }
 182+
 183+ # Make 'next' link
 184+ if ( $from ) {
 185+ $attr = array( 'title' => $nTitle, 'class' => 'mw-nextlink' );
 186+ $q = array( 'limit' => $limit, 'from' => $from, 'target' => $target );
 187+ $nlink = $skin->link( $title, $next, $attr, $q );
 188+ } else {
 189+ $nlink = $next;
 190+ }
 191+
 192+ # Make links to set number of items per page
 193+ $numLinks = array();
 194+ foreach ( array( 20, 50, 100, 250, 500 ) as $num ) {
 195+ $fmtLimit = $wgLang->formatNum( $num );
 196+
 197+ $q = array( 'offset' => $offset, 'limit' => $num, 'target' => $target );
 198+ $lTitle = wfMsgExt( 'shown-title', array( 'parsemag', 'escape' ), $num );
 199+ $attr = array( 'title' => $lTitle, 'class' => 'mw-numlink' );
 200+
 201+ $numLinks[] = $skin->link( $title, $fmtLimit, $attr, $q );
 202+ }
 203+ $nums = $wgLang->pipeList( $numLinks );
 204+
 205+ return wfMsgHtml( 'viewprevnext', $plink, $nlink, $nums );
 206+ }
 207+}
 208+
 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;
 225+
 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+}
Property changes on: branches/iwtransclusion/phase3v3/includes/specials/SpecialGlobalTemplateUsage.php
___________________________________________________________________
Added: svn:eol-style
1450 + native
Index: branches/iwtransclusion/phase3v3/languages/messages/MessagesEn.php
@@ -4577,6 +4577,18 @@
45784578 'compare-rev2' => 'Revision 2',
45794579 'compare-submit' => 'Compare',
45804580
 4581+# Special:GlobalTemplateUsage
 4582+'globaltemplateusage' => 'Global template usage',
 4583+'globaltemplateusage-for' => 'Global template usage for "$1"',
 4584+'globaltemplateusage-desc' => '[[Special:GlobalTemplateUsage|Special page]] to view global template usage',
 4585+'globaltemplateusage-ok' => 'Search',
 4586+'globaltemplateusage-text' => 'Search global template usage',
 4587+'globaltemplateusage-no-results' => '[[$1]] is not used on other wikis.',
 4588+'globaltemplateusage-on-wiki' => 'Usage on $2',
 4589+'globaltemplateusage-of-file' => 'The following other wikis use this template:',
 4590+'globaltemplateusage-more' => 'View [[{{#Special:GlobalUsage}}/$1|more global usage]] of this template.',
 4591+'globaltemplateusage-filterlocal' => 'Do not show local usage',
 4592+
45814593 # Database error messages
45824594 'dberr-header' => 'This wiki has a problem',
45834595 'dberr-problems' => 'Sorry!

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r70966Add Special:GlobalTemplateUsage to show the usage of any page on distant wiki...peter1715:19, 12 August 2010
r71049Register Special:GlobalTemplateUsage; add authors names; improve Title->getIn...peter1721:06, 13 August 2010
r83512Set $wgInternalServer to false by default, and fall back to $wgServer in the ...tstarling06:38, 8 March 2011
r87111Merge r70966, r71049reedy00:54, 29 April 2011

Status & tagging log