* New hook 'ParserTestGlobals' allows to set globals before running parser tests.
* Allow importing pages as subpage.
* Add lang and hreflang attributes to language links on Login page.
+* (bug 22749) Create Special:MostInterwikis.
=== Bug fixes in 1.20 ===
* (bug 30245) Use the correct way to construct a log page title.
'MIMEsearchPage' => 'includes/specials/SpecialMIMEsearch.php',
'MostcategoriesPage' => 'includes/specials/SpecialMostcategories.php',
'MostimagesPage' => 'includes/specials/SpecialMostimages.php',
+ 'MostinterwikisPage' => 'includes/specials/SpecialMostinterwikis.php',
'MostlinkedCategoriesPage' => 'includes/specials/SpecialMostlinkedcategories.php',
'MostlinkedPage' => 'includes/specials/SpecialMostlinked.php',
'MostlinkedTemplatesPage' => 'includes/specials/SpecialMostlinkedtemplates.php',
'Mostlinkedtemplates' => 'highuse',
'Mostcategories' => 'highuse',
'Mostimages' => 'highuse',
+ 'Mostinterwikis' => 'highuse',
'Mostrevisions' => 'highuse',
'Allpages' => 'pages',
array( 'MIMEsearchPage', 'MIMEsearch' ),
array( 'MostcategoriesPage', 'Mostcategories' ),
array( 'MostimagesPage', 'Mostimages' ),
+ array( 'MostinterwikisPage', 'Mostinterwikis' ),
array( 'MostlinkedCategoriesPage', 'Mostlinkedcategories' ),
array( 'MostlinkedtemplatesPage', 'Mostlinkedtemplates' ),
array( 'MostlinkedPage', 'Mostlinked' ),
// High use pages
'Mostlinkedcategories' => 'MostlinkedCategoriesPage',
'Mostimages' => 'MostimagesPage',
+ 'Mostinterwikis' => 'MostinterwikisPage',
'Mostlinked' => 'MostlinkedPage',
'Mostlinkedtemplates' => 'MostlinkedTemplatesPage',
'Mostcategories' => 'MostcategoriesPage',
--- /dev/null
+<?php
+/**
+ * Implements Special:Mostinterwikis
+ *
+ * Copyright © 2012 Umherirrender
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @author Umherirrender
+ */
+
+/**
+ * A special page that listed pages that have highest interwiki count
+ *
+ * @ingroup SpecialPage
+ */
+class MostinterwikisPage extends QueryPage {
+
+ function __construct( $name = 'Mostinterwikis' ) {
+ parent::__construct( $name );
+ }
+
+ function isExpensive() { return true; }
+ function isSyndicated() { return false; }
+
+ function getQueryInfo() {
+ return array (
+ 'tables' => array (
+ 'langlinks',
+ 'page'
+ ), 'fields' => array (
+ 'namespace' => 'page_namespace',
+ 'title' => 'page_title',
+ 'value' => 'COUNT(*)'
+ ), 'conds' => array (
+ 'page_namespace' => MWNamespace::getContentNamespaces()
+ ), 'options' => array (
+ 'HAVING' => 'COUNT(*) > 1',
+ 'GROUP BY' => array (
+ 'page_namespace',
+ 'page_title'
+ )
+ ), 'join_conds' => array (
+ 'page' => array (
+ 'LEFT JOIN',
+ 'page_id = ll_from'
+ )
+ )
+ );
+ }
+
+ /**
+ * Pre-fill the link cache
+ *
+ * @param $db DatabaseBase
+ * @param $res
+ */
+ function preprocessResults( $db, $res ) {
+ # There's no point doing a batch check if we aren't caching results;
+ # the page must exist for it to have been pulled out of the table
+ if ( !$this->isCached() || !$res->numRows() ) {
+ return;
+ }
+
+ $batch = new LinkBatch;
+ foreach ( $res as $row ) {
+ $batch->add( $row->namespace, $row->title );
+ }
+ $batch->execute();
+
+ // Back to start for display
+ $res->seek( 0 );
+ }
+
+ /**
+ * @param $skin Skin
+ * @param $result
+ * @return string
+ */
+ function formatResult( $skin, $result ) {
+ $title = Title::makeTitleSafe( $result->namespace, $result->title );
+ if ( !$title ) {
+ return Html::element( 'span', array( 'class' => 'mw-invalidtitle' ),
+ Linker::getInvalidTitleDescription( $this->getContext(), $result->namespace, $result->title ) );
+ }
+
+ if ( $this->isCached() ) {
+ $link = Linker::link( $title );
+ } else {
+ $link = Linker::linkKnown( $title );
+ }
+
+ $count = $this->msg( 'ninterwikis' )->numParams( $result->value )->escaped();
+
+ return $this->getLanguage()->specialList( $link, $count );
+ }
+}
'MIMEsearch' => array( 'MIMESearch' ),
'Mostcategories' => array( 'MostCategories' ),
'Mostimages' => array( 'MostLinkedFiles', 'MostFiles', 'MostImages' ),
+ 'Mostinterwikis' => array( 'MostInterwikis' ),
'Mostlinked' => array( 'MostLinkedPages', 'MostLinked' ),
'Mostlinkedcategories' => array( 'MostLinkedCategories', 'MostUsedCategories' ),
'Mostlinkedtemplates' => array( 'MostLinkedTemplates', 'MostUsedTemplates' ),
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
'ncategories' => '$1 {{PLURAL:$1|category|categories}}',
+'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwikis}}',
'nlinks' => '$1 {{PLURAL:$1|link|links}}',
'nmembers' => '$1 {{PLURAL:$1|member|members}}',
'nrevisions' => '$1 {{PLURAL:$1|revision|revisions}}',
'mostcategories-summary' => '', # do not translate or duplicate this message to other languages
'mostimages' => 'Most linked-to files',
'mostimages-summary' => '', # do not translate or duplicate this message to other languages
+'mostinterwikis' => 'Pages with the most interwikis',
+'mostinterwikis-summary' => '', # do not translate or duplicate this message to other languages
'mostrevisions' => 'Pages with the most revisions',
'mostrevisions-summary' => '', # do not translate or duplicate this message to other languages
'prefixindex' => 'All pages with prefix',
# Miscellaneous special pages
'nbytes' => 'Message used on the history page of a wiki page. Each version of a page consist of a number of bytes. $1 is the number of bytes that the page uses. Uses plural as configured for a language based on $1.',
'ncategories' => "Used in the special page '[[Special:MostCategories]]' in brackets after each entry on the list signifying how many categories a page is part of. $1 is the number of categories.",
+'ninterwikis' => "Used in the special page '[[Special:MostInterwikis]]' in brackets after each entry on the list signifying how many interwikis a page is part of. $1 is the number of interwikis.",
'nlinks' => 'This appears in brackets after each entry on the special page [[Special:MostLinked]]. $1 is the number of wiki links.',
'nmembers' => 'Appears in brackets after each category listed on the special page [[Special:WantedCategories]]. $1 is the number of members of the category.',
'nrevisions' => 'Number of revisions.',
'mostlinkedtemplates' => 'Name of special page displayed in [[Special:SpecialPages]]',
'mostcategories' => 'Name of special page displayed in [[Special:SpecialPages]]',
'mostimages' => 'Name of special page displayed in [[Special:SpecialPages]]',
+'mostinterwikis' => 'Name of special page displayed in [[Special:SpecialPages]]',
'mostrevisions' => 'Name of special page displayed in [[Special:SpecialPages]]',
'prefixindex' => 'The page title of [[Special:PrefixIndex]]. When the user limits the list to a certain namespace, {{msg-mw|allinnamespace}} is used instead.',
'prefixindex-namespace' => 'The page title of [[Special:PrefixIndex]] limited to a specific namespace. Similar to {{msg-mw|allinnamespace}}. $1 is the name of the namespace',
'mostlinkedtemplates-summary',
'mostcategories-summary',
'mostimages-summary',
+ 'mostinterwikis-summary',
'mostrevisions-summary',
'prefixindex-summary',
'shortpages-summary',
'specialpages' => array(
'nbytes',
'ncategories',
+ 'ninterwikis',
'nlinks',
'nmembers',
'nrevisions',
'mostcategories-summary',
'mostimages',
'mostimages-summary',
+ 'mostinterwikis',
+ 'mostinterwikis-summary',
'mostrevisions',
'mostrevisions-summary',
'prefixindex',