summaryrefslogtreecommitdiff
path: root/includes/specials
diff options
context:
space:
mode:
Diffstat (limited to 'includes/specials')
-rw-r--r--includes/specials/SpecialActiveusers.php37
-rw-r--r--includes/specials/SpecialAllmessages.php46
-rw-r--r--includes/specials/SpecialAllpages.php96
-rw-r--r--includes/specials/SpecialAncientpages.php8
-rw-r--r--includes/specials/SpecialBlankpage.php2
-rw-r--r--includes/specials/SpecialBlock.php100
-rw-r--r--includes/specials/SpecialBlockList.php34
-rw-r--r--includes/specials/SpecialBlockme.php6
-rw-r--r--includes/specials/SpecialBooksources.php42
-rw-r--r--includes/specials/SpecialBrokenRedirects.php63
-rw-r--r--includes/specials/SpecialCachedPage.php4
-rw-r--r--includes/specials/SpecialCategories.php8
-rw-r--r--includes/specials/SpecialChangeEmail.php14
-rw-r--r--includes/specials/SpecialChangePassword.php73
-rw-r--r--includes/specials/SpecialComparePages.php31
-rw-r--r--includes/specials/SpecialConfirmemail.php10
-rw-r--r--includes/specials/SpecialContributions.php89
-rw-r--r--includes/specials/SpecialDeadendpages.php4
-rw-r--r--includes/specials/SpecialDeletedContributions.php19
-rw-r--r--includes/specials/SpecialDisambiguations.php14
-rw-r--r--includes/specials/SpecialDoubleRedirects.php81
-rw-r--r--includes/specials/SpecialEditWatchlist.php57
-rw-r--r--includes/specials/SpecialEmailuser.php13
-rw-r--r--includes/specials/SpecialExport.php17
-rw-r--r--includes/specials/SpecialFewestrevisions.php5
-rw-r--r--includes/specials/SpecialFileDuplicateSearch.php24
-rw-r--r--includes/specials/SpecialFilepath.php6
-rw-r--r--includes/specials/SpecialImport.php36
-rw-r--r--includes/specials/SpecialJavaScriptTest.php19
-rw-r--r--includes/specials/SpecialLinkSearch.php45
-rw-r--r--includes/specials/SpecialListfiles.php12
-rw-r--r--includes/specials/SpecialListgrouprights.php26
-rw-r--r--includes/specials/SpecialListredirects.php20
-rw-r--r--includes/specials/SpecialListusers.php44
-rw-r--r--includes/specials/SpecialLockdb.php4
-rw-r--r--includes/specials/SpecialLog.php4
-rw-r--r--includes/specials/SpecialLonelypages.php9
-rw-r--r--includes/specials/SpecialLongpages.php4
-rw-r--r--includes/specials/SpecialMIMEsearch.php19
-rw-r--r--includes/specials/SpecialMergeHistory.php53
-rw-r--r--includes/specials/SpecialMostcategories.php13
-rw-r--r--includes/specials/SpecialMostimages.php12
-rw-r--r--includes/specials/SpecialMostinterwikis.php13
-rw-r--r--includes/specials/SpecialMostlinked.php15
-rw-r--r--includes/specials/SpecialMostlinkedcategories.php12
-rw-r--r--includes/specials/SpecialMostlinkedtemplates.php5
-rw-r--r--includes/specials/SpecialMostrevisions.php4
-rw-r--r--includes/specials/SpecialMovepage.php65
-rw-r--r--includes/specials/SpecialNewimages.php23
-rw-r--r--includes/specials/SpecialNewpages.php57
-rw-r--r--includes/specials/SpecialPagesWithProp.php138
-rw-r--r--includes/specials/SpecialPasswordReset.php26
-rw-r--r--includes/specials/SpecialPopularpages.php10
-rw-r--r--includes/specials/SpecialPreferences.php6
-rw-r--r--includes/specials/SpecialPrefixindex.php30
-rw-r--r--includes/specials/SpecialProtectedpages.php46
-rw-r--r--includes/specials/SpecialProtectedtitles.php28
-rw-r--r--includes/specials/SpecialRandompage.php10
-rw-r--r--includes/specials/SpecialRandomredirect.php2
-rw-r--r--includes/specials/SpecialRecentchanges.php100
-rw-r--r--includes/specials/SpecialRecentchangeslinked.php46
-rw-r--r--includes/specials/SpecialRevisiondelete.php45
-rw-r--r--includes/specials/SpecialSearch.php131
-rw-r--r--includes/specials/SpecialShortpages.php4
-rw-r--r--includes/specials/SpecialSpecialpages.php17
-rw-r--r--includes/specials/SpecialStatistics.php63
-rw-r--r--includes/specials/SpecialTags.php4
-rw-r--r--includes/specials/SpecialUnblock.php29
-rw-r--r--includes/specials/SpecialUncategorizedcategories.php13
-rw-r--r--includes/specials/SpecialUncategorizedimages.php3
-rw-r--r--includes/specials/SpecialUncategorizedpages.php11
-rw-r--r--includes/specials/SpecialUndelete.php352
-rw-r--r--includes/specials/SpecialUnlockdb.php4
-rw-r--r--includes/specials/SpecialUnusedcategories.php8
-rw-r--r--includes/specials/SpecialUnusedimages.php3
-rw-r--r--includes/specials/SpecialUnusedtemplates.php18
-rw-r--r--includes/specials/SpecialUnwatchedpages.php17
-rw-r--r--includes/specials/SpecialUpload.php98
-rw-r--r--includes/specials/SpecialUploadStash.php34
-rw-r--r--includes/specials/SpecialUserlogin.php330
-rw-r--r--includes/specials/SpecialUserlogout.php9
-rw-r--r--includes/specials/SpecialUserrights.php106
-rw-r--r--includes/specials/SpecialVersion.php137
-rw-r--r--includes/specials/SpecialWantedcategories.php4
-rw-r--r--includes/specials/SpecialWantedfiles.php6
-rw-r--r--includes/specials/SpecialWantedpages.php11
-rw-r--r--includes/specials/SpecialWantedtemplates.php4
-rw-r--r--includes/specials/SpecialWatchlist.php116
-rw-r--r--includes/specials/SpecialWhatlinkshere.php22
-rw-r--r--includes/specials/SpecialWithoutinterwiki.php4
90 files changed, 2236 insertions, 1226 deletions
diff --git a/includes/specials/SpecialActiveusers.php b/includes/specials/SpecialActiveusers.php
index c5aa2389..c9c82ada 100644
--- a/includes/specials/SpecialActiveusers.php
+++ b/includes/specials/SpecialActiveusers.php
@@ -50,7 +50,7 @@ class ActiveUsersPager extends UsersPager {
/**
* @param $context IContextSource
* @param $group null Unused
- * @param $par string Parameter passed to the page
+ * @param string $par Parameter passed to the page
*/
function __construct( IContextSource $context = null, $group = null, $par = null ) {
global $wgActiveUserDays;
@@ -93,37 +93,38 @@ class ActiveUsersPager extends UsersPager {
function getQueryInfo() {
$dbr = wfGetDB( DB_SLAVE );
$conds = array( 'rc_user > 0' ); // Users - no anons
- $conds[] = 'ipb_deleted IS NULL'; // don't show hidden names
+ if( !$this->getUser()->isAllowed( 'hideuser' ) ) {
+ $conds[] = 'ipb_deleted IS NULL OR ipb_deleted = 0'; // don't show hidden names
+ }
$conds[] = 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' );
- $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( wfTimestamp( TS_UNIX ) - $this->RCMaxAge*24*3600 ) );
+ $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes(
+ $dbr->timestamp( wfTimestamp( TS_UNIX ) - $this->RCMaxAge*24*3600 ) );
if( $this->requestedUser != '' ) {
$conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser );
}
- $query = array(
- 'tables' => array( 'recentchanges', 'user', 'ipblocks' ),
- 'fields' => array( 'user_name' => 'rc_user_text', // inheritance
+ return array(
+ 'tables' => array( 'recentchanges', 'ipblocks' ),
+ 'fields' => array(
+ 'user_name' => 'rc_user_text', // for Pager inheritance
'rc_user_text', // for Pager
- 'user_id',
+ 'user_id' => 'rc_user',
'recentedits' => 'COUNT(*)',
- 'blocked' => 'MAX(ipb_user)'
+ 'ipb_deleted' => 'MAX(ipb_deleted)'
),
'options' => array(
'GROUP BY' => array( 'rc_user_text', 'user_id' ),
'USE INDEX' => array( 'recentchanges' => 'rc_user_text' )
),
- 'join_conds' => array(
- 'user' => array( 'INNER JOIN', 'rc_user_text=user_name' ),
+ 'join_conds' => array( // check for suppression blocks
'ipblocks' => array( 'LEFT JOIN', array(
- 'user_id=ipb_user',
- 'ipb_auto' => 0,
- 'ipb_deleted' => 1
+ 'rc_user=ipb_user',
+ 'ipb_auto' => 0 # avoid duplicate blocks
)),
),
'conds' => $conds
);
- return $query;
}
function formatRow( $row ) {
@@ -162,9 +163,12 @@ class ActiveUsersPager extends UsersPager {
$groups = $lang->commaList( $list );
$item = $lang->specialList( $ulinks, $groups );
+ if( $row->ipb_deleted ) {
+ $item = "<span class=\"deleted\">$item</span>";
+ }
$count = $this->msg( 'activeusers-count' )->numParams( $row->recentedits )
->params( $userName )->numParams( $this->RCMaxAge )->escaped();
- $blocked = $row->blocked ? ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() : '';
+ $blocked = !is_null( $row->ipb_deleted ) ? ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() : '';
return Html::rawElement( 'li', array(), "{$item} [{$count}]{$blocked}" );
}
@@ -240,4 +244,7 @@ class SpecialActiveUsers extends SpecialPage {
}
}
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialAllmessages.php b/includes/specials/SpecialAllmessages.php
index fe9d41e5..a60c8efe 100644
--- a/includes/specials/SpecialAllmessages.php
+++ b/includes/specials/SpecialAllmessages.php
@@ -77,6 +77,9 @@ class SpecialAllmessages extends SpecialPage {
}
+ protected function getGroupName() {
+ return 'wiki';
+ }
}
/**
@@ -113,12 +116,12 @@ class AllmessagesTablePager extends TablePager {
$this->lang = ( $langObj ? $langObj : $wgContLang );
$this->langcode = $this->lang->getCode();
- $this->foreign = $this->langcode != $wgContLang->getCode();
+ $this->foreign = $this->langcode != $wgContLang->getCode();
$request = $this->getRequest();
$this->filter = $request->getVal( 'filter', 'all' );
- if( $this->filter === 'all' ){
+ if( $this->filter === 'all' ) {
$this->custom = null; // So won't match in either case
} else {
$this->custom = ($this->filter == 'unmodified');
@@ -126,7 +129,7 @@ class AllmessagesTablePager extends TablePager {
$prefix = $this->getLanguage()->ucfirst( $request->getVal( 'prefix', '' ) );
$prefix = $prefix != '' ? Title::makeTitleSafe( NS_MEDIAWIKI, $request->getVal( 'prefix', null ) ) : null;
- if( $prefix !== null ){
+ if( $prefix !== null ) {
$this->displayPrefix = $prefix->getDBkey();
$this->prefix = '/^' . preg_quote( $this->displayPrefix ) . '/i';
} else {
@@ -150,7 +153,7 @@ class AllmessagesTablePager extends TablePager {
$msg = wfMessage( 'allmessages-language' );
$langSelect = Xml::languageSelector( $this->langcode, false, null, $attrs, $msg );
- $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-allmessages-form' ) ) .
+ $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-allmessages-form' ) ) .
Xml::fieldset( $this->msg( 'allmessages-filter-legend' )->text() ) .
Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
Xml::openElement( 'table', array( 'class' => 'mw-allmessages-table' ) ) . "\n" .
@@ -216,7 +219,7 @@ class AllmessagesTablePager extends TablePager {
function getAllMessages( $descending ) {
wfProfileIn( __METHOD__ );
$messageNames = Language::getLocalisationCache()->getSubitemList( 'en', 'messages' );
- if( $descending ){
+ if( $descending ) {
rsort( $messageNames );
} else {
asort( $messageNames );
@@ -331,15 +334,13 @@ class AllmessagesTablePager extends TablePager {
</tr></thead><tbody>\n";
}
- function formatValue( $field, $value ){
- switch( $field ){
-
+ function formatValue( $field, $value ) {
+ switch( $field ) {
case 'am_title' :
-
$title = Title::makeTitle( NS_MEDIAWIKI, $value . $this->suffix );
- $talk = Title::makeTitle( NS_MEDIAWIKI_TALK, $value . $this->suffix );
+ $talk = Title::makeTitle( NS_MEDIAWIKI_TALK, $value . $this->suffix );
- if( $this->mCurrentRow->am_customised ){
+ if( $this->mCurrentRow->am_customised ) {
$title = Linker::linkKnown( $title, $this->getLanguage()->lcfirst( $value ) );
} else {
$title = Linker::link(
@@ -351,7 +352,7 @@ class AllmessagesTablePager extends TablePager {
);
}
if ( $this->mCurrentRow->am_talk_exists ) {
- $talk = Linker::linkKnown( $talk , $this->talk );
+ $talk = Linker::linkKnown( $talk, $this->talk );
} else {
$talk = Linker::link(
$talk,
@@ -370,12 +371,12 @@ class AllmessagesTablePager extends TablePager {
return '';
}
- function formatRow( $row ){
+ function formatRow( $row ) {
// Do all the normal stuff
$s = parent::formatRow( $row );
// But if there's a customised message, add that too.
- if( $row->am_customised ){
+ if( $row->am_customised ) {
$s .= Xml::openElement( 'tr', $this->getRowAttrs( $row, true ) );
$formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
if ( $formatted == '' ) {
@@ -387,19 +388,19 @@ class AllmessagesTablePager extends TablePager {
return $s;
}
- function getRowAttrs( $row, $isSecond = false ){
+ function getRowAttrs( $row, $isSecond = false ) {
$arr = array();
- if( $row->am_customised ){
+ if( $row->am_customised ) {
$arr['class'] = 'allmessages-customised';
}
- if( !$isSecond ){
+ if( !$isSecond ) {
$arr['id'] = Sanitizer::escapeId( 'msg_' . $this->getLanguage()->lcfirst( $row->am_title ) );
}
return $arr;
}
- function getCellAttrs( $field, $value ){
- if( $this->mCurrentRow->am_customised && $field == 'am_title' ){
+ function getCellAttrs( $field, $value ) {
+ if( $this->mCurrentRow->am_customised && $field == 'am_title' ) {
return array( 'rowspan' => '2', 'class' => $field );
} elseif( $field == 'am_title' ) {
return array( 'class' => $field );
@@ -420,16 +421,15 @@ class AllmessagesTablePager extends TablePager {
return SpecialPage::getTitleFor( 'Allmessages', false );
}
- function isFieldSortable( $x ){
+ function isFieldSortable( $x ) {
return false;
}
- function getDefaultSort(){
+ function getDefaultSort() {
return '';
}
- function getQueryInfo(){
+ function getQueryInfo() {
return '';
}
}
-
diff --git a/includes/specials/SpecialAllpages.php b/includes/specials/SpecialAllpages.php
index 0f8b2557..f9cb5cd8 100644
--- a/includes/specials/SpecialAllpages.php
+++ b/includes/specials/SpecialAllpages.php
@@ -59,16 +59,16 @@ class SpecialAllpages extends IncludableSpecialPage {
/**
* Constructor
*
- * @param $name string: name of the special page, as seen in links and URLs (default: 'Allpages')
+ * @param string $name name of the special page, as seen in links and URLs (default: 'Allpages')
*/
- function __construct( $name = 'Allpages' ){
+ function __construct( $name = 'Allpages' ) {
parent::__construct( $name );
}
/**
* Entry point : initialise variables and call subfunctions.
*
- * @param $par String: becomes "FOO" when called like Special:Allpages/FOO (default NULL)
+ * @param string $par becomes "FOO" when called like Special:Allpages/FOO (default NULL)
*/
function execute( $par ) {
global $wgContLang;
@@ -107,16 +107,16 @@ class SpecialAllpages extends IncludableSpecialPage {
* HTML for the top form
*
* @param $namespace Integer: a namespace constant (default NS_MAIN).
- * @param $from String: dbKey we are starting listing at.
- * @param $to String: dbKey we are ending listing at.
- * @param $hideredirects Bool: dont show redirects (default FALSE)
+ * @param string $from dbKey we are starting listing at.
+ * @param string $to dbKey we are ending listing at.
+ * @param bool $hideredirects dont show redirects (default FALSE)
* @return string
*/
function namespaceForm( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) {
global $wgScript;
$t = $this->getTitle();
- $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
+ $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
$out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
$out .= Html::hidden( 'title', $t->getPrefixedText() );
$out .= Xml::openElement( 'fieldset' );
@@ -127,7 +127,7 @@ class SpecialAllpages extends IncludableSpecialPage {
Xml::label( $this->msg( 'allpagesfrom' )->text(), 'nsfrom' ) .
" </td>
<td class='mw-input'>" .
- Xml::input( 'from', 30, str_replace('_',' ',$from), array( 'id' => 'nsfrom' ) ) .
+ Xml::input( 'from', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) .
" </td>
</tr>
<tr>
@@ -135,7 +135,7 @@ class SpecialAllpages extends IncludableSpecialPage {
Xml::label( $this->msg( 'allpagesto' )->text(), 'nsto' ) .
" </td>
<td class='mw-input'>" .
- Xml::input( 'to', 30, str_replace('_',' ',$to), array( 'id' => 'nsto' ) ) .
+ Xml::input( 'to', 30, str_replace( '_', ' ', $to ), array( 'id' => 'nsto' ) ) .
" </td>
</tr>
<tr>
@@ -165,9 +165,9 @@ class SpecialAllpages extends IncludableSpecialPage {
/**
* @param $namespace Integer (default NS_MAIN)
- * @param $from String: list all pages from this name
- * @param $to String: list all pages to this name
- * @param $hideredirects Bool: dont show redirects (default FALSE)
+ * @param string $from list all pages from this name
+ * @param string $to list all pages to this name
+ * @param bool $hideredirects dont show redirects (default FALSE)
*/
function showToplevel( $namespace = NS_MAIN, $from = '', $to = '', $hideredirects = false ) {
$output = $this->getOutput();
@@ -180,7 +180,7 @@ class SpecialAllpages extends IncludableSpecialPage {
$where = array( 'page_namespace' => $namespace );
if ( $hideredirects ) {
- $where[ 'page_is_redirect' ] = 0;
+ $where['page_is_redirect'] = 0;
}
$from = Title::makeTitleSafe( $namespace, $from );
@@ -188,18 +188,18 @@ class SpecialAllpages extends IncludableSpecialPage {
$from = ( $from && $from->isLocal() ) ? $from->getDBkey() : null;
$to = ( $to && $to->isLocal() ) ? $to->getDBkey() : null;
- if( isset($from) )
- $where[] = 'page_title >= '.$dbr->addQuotes( $from );
- if( isset($to) )
- $where[] = 'page_title <= '.$dbr->addQuotes( $to );
+ if( isset( $from ) )
+ $where[] = 'page_title >= ' . $dbr->addQuotes( $from );
+ if( isset( $to ) )
+ $where[] = 'page_title <= ' . $dbr->addQuotes( $to );
global $wgMemc;
- $key = wfMemcKey( 'allpages', 'ns', $namespace, $from, $to );
+ $key = wfMemcKey( 'allpages', 'ns', $namespace, sha1( $from ), sha1( $to ) );
$lines = $wgMemc->get( $key );
$count = $dbr->estimateRowCount( 'page', '*', $where, __METHOD__ );
- $maxPerSubpage = intval($count/$this->maxLineCount);
- $maxPerSubpage = max($maxPerSubpage,$this->maxPerPage);
+ $maxPerSubpage = intval( $count / $this->maxLineCount );
+ $maxPerSubpage = max( $maxPerSubpage, $this->maxPerPage );
if( !is_array( $lines ) ) {
$options = array( 'LIMIT' => 1 );
@@ -217,9 +217,9 @@ class SpecialAllpages extends IncludableSpecialPage {
: array( 'page_title >= ' . $dbr->addQuotes( $lastTitle ) );
$res = $dbr->select( 'page', /* FROM */
'page_title', /* WHAT */
- array_merge($where,$chunk),
+ array_merge( $where, $chunk ),
__METHOD__,
- array ('LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC')
+ array( 'LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC' )
);
$s = $dbr->fetchObject( $res );
@@ -228,7 +228,7 @@ class SpecialAllpages extends IncludableSpecialPage {
} else {
// Final chunk, but ended prematurely. Go back and find the end.
$endTitle = $dbr->selectField( 'page', 'MAX(page_title)',
- array_merge($where,$chunk),
+ array_merge( $where, $chunk ),
__METHOD__ );
array_push( $lines, $endTitle );
$done = true;
@@ -250,7 +250,7 @@ class SpecialAllpages extends IncludableSpecialPage {
// If there are only two or less sections, don't even display them.
// Instead, display the first section directly.
if( count( $lines ) <= 2 ) {
- if( !empty($lines) ) {
+ if( !empty( $lines ) ) {
$this->showChunk( $namespace, $from, $to, $hideredirects );
} else {
$output->addHTML( $this->namespaceForm( $namespace, $from, $to, $hideredirects ) );
@@ -272,7 +272,7 @@ class SpecialAllpages extends IncludableSpecialPage {
if( $this->including() ) {
$out2 = '';
} else {
- if( isset($from) || isset($to) ) {
+ if( isset( $from ) || isset( $to ) ) {
$out2 = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-form' ) ).
'<tr>
<td>' .
@@ -294,10 +294,10 @@ class SpecialAllpages extends IncludableSpecialPage {
/**
* Show a line of "ABC to DEF" ranges of articles
*
- * @param $inpoint String: lower limit of pagenames
- * @param $outpoint String: upper limit of pagenames
+ * @param string $inpoint lower limit of pagenames
+ * @param string $outpoint upper limit of pagenames
* @param $namespace Integer (Default NS_MAIN)
- * @param $hideredirects Bool: dont show redirects (default FALSE)
+ * @param bool $hideredirects dont show redirects (default FALSE)
* @return string
*/
function showline( $inpoint, $outpoint, $namespace = NS_MAIN, $hideredirects ) {
@@ -311,12 +311,12 @@ class SpecialAllpages extends IncludableSpecialPage {
$queryparams = $namespace ? "namespace=$namespace&" : '';
$queryhideredirects = array();
- if ($hideredirects) {
- $queryhideredirects[ 'hideredirects' ] = 1;
+ if ( $hideredirects ) {
+ $queryhideredirects['hideredirects'] = 1;
}
$special = $this->getTitle();
- $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode($inpoint) . '&to=' . urlencode($outpoint), $queryhideredirects ) );
+ $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode( $inpoint ) . '&to=' . urlencode( $outpoint ), $queryhideredirects ) );
$out = $this->msg( 'alphaindexline' )->rawParams(
"<a href=\"$link\">$inpointf</a></td><td>",
@@ -327,15 +327,15 @@ class SpecialAllpages extends IncludableSpecialPage {
/**
* @param $namespace Integer (Default NS_MAIN)
- * @param $from String: list all pages from this name (default FALSE)
- * @param $to String: list all pages to this name (default FALSE)
- * @param $hideredirects Bool: dont show redirects (default FALSE)
+ * @param string $from list all pages from this name (default FALSE)
+ * @param string $to list all pages to this name (default FALSE)
+ * @param bool $hideredirects dont show redirects (default FALSE)
*/
function showChunk( $namespace = NS_MAIN, $from = false, $to = false, $hideredirects = false ) {
global $wgContLang;
$output = $this->getOutput();
- $fromList = $this->getNamespaceKeyAndText($namespace, $from);
+ $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
$toList = $this->getNamespaceKeyAndText( $namespace, $to );
$namespaces = $wgContLang->getNamespaces();
$n = 0;
@@ -357,7 +357,7 @@ class SpecialAllpages extends IncludableSpecialPage {
);
if ( $hideredirects ) {
- $conds[ 'page_is_redirect' ] = 0;
+ $conds['page_is_redirect'] = 0;
}
if( $toKey !== "" ) {
@@ -416,10 +416,10 @@ class SpecialAllpages extends IncludableSpecialPage {
$res_prev = $dbr->select(
'page',
'page_title',
- array( 'page_namespace' => $namespace, 'page_title < '.$dbr->addQuotes($from) ),
+ array( 'page_namespace' => $namespace, 'page_title < ' . $dbr->addQuotes( $from ) ),
__METHOD__,
array( 'ORDER BY' => 'page_title DESC',
- 'LIMIT' => $this->maxPerPage, 'OFFSET' => ($this->maxPerPage - 1 )
+ 'LIMIT' => $this->maxPerPage, 'OFFSET' => ( $this->maxPerPage - 1 )
)
);
@@ -438,7 +438,7 @@ class SpecialAllpages extends IncludableSpecialPage {
array( 'page_namespace' => $namespace ), __METHOD__, $options );
# Show the previous link if it s not the current requested chunk
if( $from != $reallyFirstPage_title ) {
- $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
+ $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
} else {
$prevTitle = null;
}
@@ -457,7 +457,7 @@ class SpecialAllpages extends IncludableSpecialPage {
Linker::link( $self, $this->msg( 'allpages' )->escaped() );
# Do we put a previous link ?
- if( isset( $prevTitle ) && $pt = $prevTitle->getText() ) {
+ if( isset( $prevTitle ) && $pt = $prevTitle->getText() ) {
$query = array( 'from' => $prevTitle->getText() );
if( $namespace )
@@ -477,7 +477,7 @@ class SpecialAllpages extends IncludableSpecialPage {
if( $n == $this->maxPerPage && $s = $res->fetchObject() ) {
# $s is the first link of the next chunk
- $t = Title::makeTitle($namespace, $s->page_title);
+ $t = Title::makeTitle( $namespace, $s->page_title );
$query = array( 'from' => $t->getText() );
if( $namespace )
@@ -515,14 +515,14 @@ class SpecialAllpages extends IncludableSpecialPage {
/**
* @param $ns Integer: the namespace of the article
- * @param $text String: the name of the article
+ * @param string $text the name of the article
* @return array( int namespace, string dbkey, string pagename ) or NULL on error
*/
- protected function getNamespaceKeyAndText($ns, $text) {
+ protected function getNamespaceKeyAndText( $ns, $text ) {
if ( $text == '' )
return array( $ns, '', '' ); # shortcut for common case
- $t = Title::makeTitleSafe($ns, $text);
+ $t = Title::makeTitleSafe( $ns, $text );
if ( $t && $t->isLocal() ) {
return array( $t->getNamespace(), $t->getDBkey(), $t->getText() );
} elseif ( $t ) {
@@ -530,12 +530,16 @@ class SpecialAllpages extends IncludableSpecialPage {
}
# try again, in case the problem was an empty pagename
- $text = preg_replace('/(#|$)/', 'X$1', $text);
- $t = Title::makeTitleSafe($ns, $text);
+ $text = preg_replace( '/(#|$)/', 'X$1', $text );
+ $t = Title::makeTitleSafe( $ns, $text );
if ( $t && $t->isLocal() ) {
return array( $t->getNamespace(), '', '' );
} else {
return null;
}
}
+
+ protected function getGroupName() {
+ return 'pages';
+ }
}
diff --git a/includes/specials/SpecialAncientpages.php b/includes/specials/SpecialAncientpages.php
index 6e3d49bd..b0f333c4 100644
--- a/includes/specials/SpecialAncientpages.php
+++ b/includes/specials/SpecialAncientpages.php
@@ -36,7 +36,9 @@ class AncientPagesPage extends QueryPage {
return true;
}
- function isSyndicated() { return false; }
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array(
@@ -69,4 +71,8 @@ class AncientPagesPage extends QueryPage {
);
return $this->getLanguage()->specialList( $link, htmlspecialchars( $d ) );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialBlankpage.php b/includes/specials/SpecialBlankpage.php
index 42d33779..bfa2f951 100644
--- a/includes/specials/SpecialBlankpage.php
+++ b/includes/specials/SpecialBlankpage.php
@@ -33,6 +33,6 @@ class SpecialBlankpage extends UnlistedSpecialPage {
}
public function execute( $par ) {
$this->setHeaders();
- $this->getOutput()->addWikiMsg('intentionallyblankpage');
+ $this->getOutput()->addWikiMsg( 'intentionallyblankpage' );
}
}
diff --git a/includes/specials/SpecialBlock.php b/includes/specials/SpecialBlock.php
index 1d6656ab..50fdbc26 100644
--- a/includes/specials/SpecialBlock.php
+++ b/includes/specials/SpecialBlock.php
@@ -62,7 +62,7 @@ class SpecialBlock extends FormSpecialPage {
* @throws ErrorPageError
*/
protected function checkExecutePermissions( User $user ) {
- parent::checkExecutePermissions( $user );
+ parent::checkExecutePermissions( $user );
# bug 15810: blocked admins should have limited access here
$status = self::checkUnblockSelf( $this->target, $user );
@@ -134,6 +134,7 @@ class SpecialBlock extends FormSpecialPage {
'tabindex' => '1',
'id' => 'mw-bi-target',
'size' => '45',
+ 'autofocus' => true,
'required' => true,
'validation-callback' => array( __CLASS__, 'validateTargetField' ),
),
@@ -224,7 +225,7 @@ class SpecialBlock extends FormSpecialPage {
/**
* If the user has already been blocked with similar settings, load that block
* and change the defaults for the form fields to match the existing settings.
- * @param $fields Array HTMLForm descriptor array
+ * @param array $fields HTMLForm descriptor array
* @return Bool whether fields were altered (that is, whether the target is
* already blocked)
*/
@@ -239,7 +240,7 @@ class SpecialBlock extends FormSpecialPage {
if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
&& ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
- || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
+ || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
)
{
$fields['HardBlock']['default'] = $block->isHardblock();
@@ -386,7 +387,7 @@ class SpecialBlock extends FormSpecialPage {
);
}
- $text = Html::rawElement(
+ $text = Html::rawElement(
'p',
array( 'class' => 'mw-ipb-conveniencelinks' ),
$this->getLanguage()->pipeList( $links )
@@ -450,7 +451,7 @@ class SpecialBlock extends FormSpecialPage {
/**
* Determine the target of the block, and the type of target
* TODO: should be in Block.php?
- * @param $par String subpage parameter passed to setup, or data value from
+ * @param string $par subpage parameter passed to setup, or data value from
* the HTMLForm
* @param $request WebRequest optionally try and get data from a request too
* @return array( User|string|null, Block::TYPE_ constant|null )
@@ -507,53 +508,74 @@ class SpecialBlock extends FormSpecialPage {
* @return Message
*/
public static function validateTargetField( $value, $alldata, $form ) {
+ $status = self::validateTarget( $value, $form->getUser() );
+ if ( !$status->isOK() ) {
+ $errors = $status->getErrorsArray();
+ return call_user_func_array( array( $form, 'msg' ), $errors[0] );
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Validate a block target.
+ *
+ * @since 1.21
+ * @param string $value Block target to check
+ * @param User $user Performer of the block
+ * @return Status
+ */
+ public static function validateTarget( $value, User $user ) {
global $wgBlockCIDRLimit;
list( $target, $type ) = self::getTargetAndType( $value );
+ $status = Status::newGood( $target );
if ( $type == Block::TYPE_USER ) {
- # TODO: why do we not have a User->exists() method?
- if ( !$target->getId() ) {
- return $form->msg( 'nosuchusershort',
- wfEscapeWikiText( $target->getName() ) );
+ if ( $target->isAnon() ) {
+ $status->fatal(
+ 'nosuchusershort',
+ wfEscapeWikiText( $target->getName() )
+ );
}
- $status = self::checkUnblockSelf( $target, $form->getUser() );
- if ( $status !== true ) {
- return $form->msg( 'badaccess', $status );
+ $unblockStatus = self::checkUnblockSelf( $target, $user );
+ if ( $unblockStatus !== true ) {
+ $status->fatal( 'badaccess', $unblockStatus );
}
-
} elseif ( $type == Block::TYPE_RANGE ) {
list( $ip, $range ) = explode( '/', $target, 2 );
- if ( ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 )
- || ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 ) )
- {
- # Range block effectively disabled
- return $form->msg( 'range_block_disabled' );
+ if (
+ ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 ) ||
+ ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 )
+ ) {
+ // Range block effectively disabled
+ $status->fatal( 'range_block_disabled' );
}
- if ( ( IP::isIPv4( $ip ) && $range > 32 )
- || ( IP::isIPv6( $ip ) && $range > 128 ) )
- {
- # Dodgy range
- return $form->msg( 'ip_range_invalid' );
+ if (
+ ( IP::isIPv4( $ip ) && $range > 32 ) ||
+ ( IP::isIPv6( $ip ) && $range > 128 )
+ ) {
+ // Dodgy range
+ $status->fatal( 'ip_range_invalid' );
}
if ( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
- return $form->msg( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
+ $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
}
if ( IP::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
- return $form->msg( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
+ $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
}
} elseif ( $type == Block::TYPE_IP ) {
# All is well
} else {
- return $form->msg( 'badipaddress' );
+ $status->fatal( 'badipaddress' );
}
- return true;
+ return $status;
}
/**
@@ -629,7 +651,7 @@ class SpecialBlock extends FormSpecialPage {
}
if ( $data['HideUser'] ) {
- if ( !$performer->isAllowed('hideuser') ) {
+ if ( !$performer->isAllowed( 'hideuser' ) ) {
# this codepath is unreachable except by a malicious user spoofing forms,
# or by race conditions (user has oversight and sysop, loads block form,
# and is de-oversighted before submission); so need to fail completely
@@ -672,10 +694,16 @@ class SpecialBlock extends FormSpecialPage {
# Try to insert block. Is there a conflicting block?
$status = $block->insert();
if ( !$status ) {
+ # Indicates whether the user is confirming the block and is aware of
+ # the conflict (did not change the block target in the meantime)
+ $blockNotConfirmed = !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
+ && $data['PreviousTarget'] !== $target );
+
+ # Special case for API - bug 32434
+ $reblockNotAllowed = ( array_key_exists( 'Reblock', $data ) && !$data['Reblock'] );
+
# Show form unless the user is already aware of this...
- if ( !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
- && $data['PreviousTarget'] !== $target ) )
- {
+ if( $blockNotConfirmed || $reblockNotAllowed ) {
return array( array( 'ipb_already_blocked', $block->getTarget() ) );
# Otherwise, try to update the block...
} else {
@@ -742,7 +770,7 @@ class SpecialBlock extends FormSpecialPage {
$logParams
);
# Relate log ID to block IDs (bug 25763)
- $blockIds = array_merge( array( $status['id'] ), $status['autoIds'] );
+ $blockIds = array_merge( array( $status['id'] ), $status['autoIds'] );
$log->addRelations( 'ipb_id', $blockIds, $log_id );
# Report to the user
@@ -782,7 +810,7 @@ class SpecialBlock extends FormSpecialPage {
/**
* Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
* ("24 May 2034", etc), into an absolute timestamp we can put into the database.
- * @param $expiry String: whatever was typed into the form
+ * @param string $expiry whatever was typed into the form
* @return String: timestamp or "infinity" string for the DB implementation
*/
public static function parseExpiryInput( $expiry ) {
@@ -855,7 +883,7 @@ class SpecialBlock extends FormSpecialPage {
/**
* Return a comma-delimited list of "flags" to be passed to the log
* reader for this block, to provide more information in the logs
- * @param $data Array from HTMLForm data
+ * @param array $data from HTMLForm data
* @param $type Block::TYPE_ constant (USER, RANGE, or IP)
* @return string
*/
@@ -918,6 +946,10 @@ class SpecialBlock extends FormSpecialPage {
$out->setPageTitle( $this->msg( 'blockipsuccesssub' ) );
$out->addWikiMsg( 'blockipsuccesstext', wfEscapeWikiText( $this->target ) );
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
# BC @since 1.18
diff --git a/includes/specials/SpecialBlockList.php b/includes/specials/SpecialBlockList.php
index 7143d5bc..e10df4fe 100644
--- a/includes/specials/SpecialBlockList.php
+++ b/includes/specials/SpecialBlockList.php
@@ -37,7 +37,7 @@ class SpecialBlockList extends SpecialPage {
/**
* Main execution point
*
- * @param $par String title fragment
+ * @param string $par title fragment
*/
public function execute( $par ) {
$this->setHeaders();
@@ -113,14 +113,14 @@ class SpecialBlockList extends SpecialPage {
$conds = array();
# Is the user allowed to see hidden blocks?
- if ( !$this->getUser()->isAllowed( 'hideuser' ) ){
+ if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
$conds['ipb_deleted'] = 0;
}
- if ( $this->target !== '' ){
+ if ( $this->target !== '' ) {
list( $target, $type ) = Block::parseTarget( $this->target );
- switch( $type ){
+ switch( $type ) {
case Block::TYPE_ID:
case Block::TYPE_AUTO:
$conds['ipb_id'] = $target;
@@ -205,6 +205,10 @@ class SpecialBlockList extends SpecialPage {
$out->addHTML( Html::rawElement( 'ul', array( 'class' => 'mw-ipblocklist-otherblocks' ), $list ) . "\n" );
}
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
class BlockListPager extends TablePager {
@@ -269,11 +273,11 @@ class BlockListPager extends TablePager {
break;
case 'ipb_target':
- if( $row->ipb_auto ){
+ if( $row->ipb_auto ) {
$formatted = $this->msg( 'autoblockid', $row->ipb_id )->parse();
} else {
list( $target, $type ) = Block::parseTarget( $row->ipb_address );
- switch( $type ){
+ switch( $type ) {
case Block::TYPE_USER:
case Block::TYPE_IP:
$formatted = Linker::userLink( $target->getId(), $target );
@@ -292,8 +296,8 @@ class BlockListPager extends TablePager {
case 'ipb_expiry':
$formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */ true );
- if( $this->getUser()->isAllowed( 'block' ) ){
- if( $row->ipb_auto ){
+ if( $this->getUser()->isAllowed( 'block' ) ) {
+ if( $row->ipb_auto ) {
$links[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'Unblock' ),
$msg['unblocklink'],
@@ -329,7 +333,7 @@ class BlockListPager extends TablePager {
break;
case 'ipb_reason':
- $formatted = Linker::commentBlock( $value );
+ $formatted = Linker::formatComment( $value );
break;
case 'ipb_params':
@@ -391,14 +395,14 @@ class BlockListPager extends TablePager {
);
# Is the user allowed to see hidden blocks?
- if ( !$this->getUser()->isAllowed( 'hideuser' ) ){
+ if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
$info['conds']['ipb_deleted'] = 0;
}
return $info;
}
- public function getTableClass(){
+ public function getTableClass() {
return 'TablePager mw-blocklist';
}
@@ -418,7 +422,7 @@ class BlockListPager extends TablePager {
* Do a LinkBatch query to minimise database load when generating all these links
* @param $result
*/
- function preprocessResults( $result ){
+ function preprocessResults( $result ) {
wfProfileIn( __METHOD__ );
# Do a link batch query
$lb = new LinkBatch;
@@ -437,11 +441,11 @@ class BlockListPager extends TablePager {
}
$ua = UserArray::newFromIDs( $userids );
- foreach( $ua as $user ){
+ foreach( $ua as $user ) {
$name = str_replace( ' ', '_', $user->getName() );
$lb->add( NS_USER, $name );
$lb->add( NS_USER_TALK, $name );
- }
+ }
$lb->execute();
wfProfileOut( __METHOD__ );
@@ -472,7 +476,7 @@ class HTMLBlockedUsersItemSelect extends HTMLSelectField {
// This adds the explicitly requested limit value to the drop-down,
// then makes sure it's sorted correctly so when we output the list
// later, the custom option doesn't just show up last.
- $this->mParams['options'][ $this->mParent->getLanguage()->formatNum( $value ) ] = intval($value);
+ $this->mParams['options'][$this->mParent->getLanguage()->formatNum( $value )] = intval( $value );
asort( $this->mParams['options'] );
}
diff --git a/includes/specials/SpecialBlockme.php b/includes/specials/SpecialBlockme.php
index 3840b2ff..85a3019e 100644
--- a/includes/specials/SpecialBlockme.php
+++ b/includes/specials/SpecialBlockme.php
@@ -22,7 +22,7 @@
*/
/**
- * A special page called by proxy_check.php to block open proxies
+ * A special page called by proxyCheck.php to block open proxies
*
* @ingroup SpecialPage
*/
@@ -59,4 +59,8 @@ class SpecialBlockme extends UnlistedSpecialPage {
$this->getOutput()->addWikiMsg( 'proxyblocksuccess' );
}
+
+ protected function getGroupName() {
+ return 'other';
+ }
}
diff --git a/includes/specials/SpecialBooksources.php b/includes/specials/SpecialBooksources.php
index bf7de3f5..bdbd77b8 100644
--- a/includes/specials/SpecialBooksources.php
+++ b/includes/specials/SpecialBooksources.php
@@ -46,7 +46,7 @@ class SpecialBookSources extends SpecialPage {
/**
* Show the special page
*
- * @param $isbn string ISBN passed as a subpage parameter
+ * @param string $isbn ISBN passed as a subpage parameter
*/
public function execute( $isbn ) {
$this->setHeaders();
@@ -62,8 +62,8 @@ class SpecialBookSources extends SpecialPage {
}
/**
- * Returns whether a given ISBN (10 or 13) is valid. True indicates validity.
- * @param isbn string ISBN passed for check
+ * Returns whether a given ISBN (10 or 13) is valid. True indicates validity.
+ * @param string $isbn ISBN passed for check
* @return bool
*/
public static function isValidISBN( $isbn ) {
@@ -71,7 +71,7 @@ class SpecialBookSources extends SpecialPage {
$sum = 0;
if( strlen( $isbn ) == 13 ) {
for( $i = 0; $i < 12; $i++ ) {
- if($i % 2 == 0) {
+ if( $i % 2 == 0 ) {
$sum += $isbn[$i];
} else {
$sum += 3 * $isbn[$i];
@@ -79,19 +79,19 @@ class SpecialBookSources extends SpecialPage {
}
$check = (10 - ($sum % 10)) % 10;
- if ($check == $isbn[12]) {
+ if ( $check == $isbn[12] ) {
return true;
}
} elseif( strlen( $isbn ) == 10 ) {
- for($i = 0; $i < 9; $i++) {
+ for( $i = 0; $i < 9; $i++ ) {
$sum += $isbn[$i] * ($i + 1);
}
$check = $sum % 11;
- if($check == 10) {
+ if( $check == 10 ) {
$check = "X";
}
- if($check == $isbn[9]) {
+ if( $check == $isbn[9] ) {
return true;
}
}
@@ -101,7 +101,7 @@ class SpecialBookSources extends SpecialPage {
/**
* Trim ISBN and remove characters which aren't required
*
- * @param $isbn string Unclean ISBN
+ * @param string $isbn Unclean ISBN
* @return string
*/
private static function cleanIsbn( $isbn ) {
@@ -116,7 +116,7 @@ class SpecialBookSources extends SpecialPage {
private function makeForm() {
global $wgScript;
- $form = '<fieldset><legend>' . $this->msg( 'booksources-search-legend' )->escaped() . '</legend>';
+ $form = '<fieldset><legend>' . $this->msg( 'booksources-search-legend' )->escaped() . '</legend>';
$form .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
$form .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() );
$form .= '<p>' . Xml::inputLabel( $this->msg( 'booksources-isbn' )->text(), 'isbn', 'isbn', 20, $this->isbn );
@@ -130,6 +130,7 @@ class SpecialBookSources extends SpecialPage {
* Determine where to get the list of book sources from,
* format and output them
*
+ * @throws MWException
* @return string
*/
private function showList() {
@@ -144,8 +145,17 @@ class SpecialBookSources extends SpecialPage {
$title = Title::makeTitleSafe( NS_PROJECT, $page ); # Show list in content language
if( is_object( $title ) && $title->exists() ) {
$rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
- $this->getOutput()->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $rev->getText() ) );
- return true;
+ $content = $rev->getContent();
+
+ if ( $content instanceof TextContent ) {
+ //XXX: in the future, this could be stored as structured data, defining a list of book sources
+
+ $text = $content->getNativeData();
+ $this->getOutput()->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $text ) );
+ return true;
+ } else {
+ throw new MWException( "Unexpected content type for book sources: " . $content->getModel() );
+ }
}
# Fall back to the defaults given in the language file
@@ -161,12 +171,16 @@ class SpecialBookSources extends SpecialPage {
/**
* Format a book source list item
*
- * @param $label string Book source label
- * @param $url string Book source URL
+ * @param string $label Book source label
+ * @param string $url Book source URL
* @return string
*/
private function makeListItem( $label, $url ) {
$url = str_replace( '$1', $this->isbn, $url );
return '<li><a href="' . htmlspecialchars( $url ) . '" class="external">' . htmlspecialchars( $label ) . '</a></li>';
}
+
+ protected function getGroupName() {
+ return 'other';
+ }
}
diff --git a/includes/specials/SpecialBrokenRedirects.php b/includes/specials/SpecialBrokenRedirects.php
index 8119e6d1..fac41236 100644
--- a/includes/specials/SpecialBrokenRedirects.php
+++ b/includes/specials/SpecialBrokenRedirects.php
@@ -33,35 +33,54 @@ class BrokenRedirectsPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
- function sortDescending() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function sortDescending() {
+ return false;
+ }
function getPageHeader() {
return $this->msg( 'brokenredirectstext' )->parseAsBlock();
}
function getQueryInfo() {
+ $dbr = wfGetDB( DB_SLAVE );
return array(
- 'tables' => array( 'redirect', 'p1' => 'page',
- 'p2' => 'page' ),
- 'fields' => array( 'namespace' => 'p1.page_namespace',
- 'title' => 'p1.page_title',
- 'value' => 'p1.page_title',
- 'rd_namespace',
- 'rd_title'
+ 'tables' => array(
+ 'redirect',
+ 'p1' => 'page',
+ 'p2' => 'page',
),
- 'conds' => array( 'rd_namespace >= 0',
- 'p2.page_namespace IS NULL'
+ 'fields' => array(
+ 'namespace' => 'p1.page_namespace',
+ 'title' => 'p1.page_title',
+ 'value' => 'p1.page_title',
+ 'rd_namespace',
+ 'rd_title',
+ ),
+ 'conds' => array(
+ // Exclude pages that don't exist locally as wiki pages,
+ // but aren't "broken" either.
+ // Special pages and interwiki links
+ 'rd_namespace >= 0',
+ 'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ),
+ 'p2.page_namespace IS NULL',
+ ),
+ 'join_conds' => array(
+ 'p1' => array( 'JOIN', array(
+ 'rd_from=p1.page_id',
+ ) ),
+ 'p2' => array( 'LEFT JOIN', array(
+ 'rd_namespace=p2.page_namespace',
+ 'rd_title=p2.page_title'
+ ) ),
),
- 'join_conds' => array( 'p1' => array( 'JOIN', array(
- 'rd_from=p1.page_id',
- ) ),
- 'p2' => array( 'LEFT JOIN', array(
- 'rd_namespace=p2.page_namespace',
- 'rd_title=p2.page_title'
- ) )
- )
);
}
@@ -132,4 +151,8 @@ class BrokenRedirectsPage extends QueryPage {
$out .= " {$arr} {$to}";
return $out;
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialCachedPage.php b/includes/specials/SpecialCachedPage.php
index b3f6c720..ddd11ad0 100644
--- a/includes/specials/SpecialCachedPage.php
+++ b/includes/specials/SpecialCachedPage.php
@@ -119,7 +119,7 @@ abstract class SpecialCachedPage extends SpecialPage implements ICacheHelper {
*
* @since 1.20
*
- * @param {function} $computeFunction
+ * @param callable $computeFunction
* @param array|mixed $args
* @param string|null $key
*
@@ -137,7 +137,7 @@ abstract class SpecialCachedPage extends SpecialPage implements ICacheHelper {
*
* @since 1.20
*
- * @param {function} $computeFunction
+ * @param callable $computeFunction
* @param array $args
* @param string|null $key
*/
diff --git a/includes/specials/SpecialCategories.php b/includes/specials/SpecialCategories.php
index 1232e3fa..9040c640 100644
--- a/includes/specials/SpecialCategories.php
+++ b/includes/specials/SpecialCategories.php
@@ -50,6 +50,10 @@ class SpecialCategories extends SpecialPage {
Html::closeElement( 'div' )
);
}
+
+ protected function getGroupName() {
+ return 'pages';
+ }
}
/**
@@ -72,7 +76,7 @@ class CategoryPager extends AlphabeticPager {
function getQueryInfo() {
return array(
'tables' => array( 'category' ),
- 'fields' => array( 'cat_title','cat_pages' ),
+ 'fields' => array( 'cat_title', 'cat_pages' ),
'conds' => array( 'cat_pages > 0' ),
'options' => array( 'USE INDEX' => 'cat_title' ),
);
@@ -112,7 +116,7 @@ class CategoryPager extends AlphabeticPager {
return parent::getBody();
}
- function formatRow($result) {
+ function formatRow( $result ) {
$title = Title::makeTitle( NS_CATEGORY, $result->cat_title );
$titleText = Linker::link( $title, htmlspecialchars( $title->getText() ) );
$count = $this->msg( 'nmembers' )->numParams( $result->cat_pages )->escaped();
diff --git a/includes/specials/SpecialChangeEmail.php b/includes/specials/SpecialChangeEmail.php
index fc726106..59a02578 100644
--- a/includes/specials/SpecialChangeEmail.php
+++ b/includes/specials/SpecialChangeEmail.php
@@ -151,10 +151,10 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
$items = array(
array( 'wpName', 'username', 'text', $user->getName() ),
array( 'wpOldEmail', 'changeemail-oldemail', 'text', $oldEmailText ),
- array( 'wpNewEmail', 'changeemail-newemail', 'input', $this->mNewEmail ),
+ array( 'wpNewEmail', 'changeemail-newemail', 'email', $this->mNewEmail ),
);
if ( $wgRequirePasswordforEmailChange ) {
- $items[] = array( 'wpPassword', 'yourpassword', 'password', $this->mPassword );
+ $items[] = array( 'wpPassword', 'changeemail-password', 'password', $this->mPassword );
}
$this->getOutput()->addHTML(
@@ -195,7 +195,7 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
if ( $type != 'text' ) {
$out .= Xml::label( $this->msg( $label )->text(), $name );
} else {
- $out .= $this->msg( $label )->escaped();
+ $out .= $this->msg( $label )->escaped();
}
$out .= "</td>\n";
$out .= "\t<td class='mw-input'>";
@@ -213,6 +213,8 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
* @return bool|string true or string on success, false on failure
*/
protected function attemptChange( User $user, $pass, $newaddr ) {
+ global $wgAuth;
+
if ( $newaddr != '' && !Sanitizer::validateEmail( $newaddr ) ) {
$this->error( 'invalidemailaddress' );
return false;
@@ -248,6 +250,12 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
$user->saveSettings();
+ $wgAuth->updateExternalDB( $user );
+
return $status->value;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialChangePassword.php b/includes/specials/SpecialChangePassword.php
index ba728ac2..e538caca 100644
--- a/includes/specials/SpecialChangePassword.php
+++ b/includes/specials/SpecialChangePassword.php
@@ -27,6 +27,9 @@
* @ingroup SpecialPage
*/
class SpecialChangePassword extends UnlistedSpecialPage {
+
+ protected $mUserName, $mOldpass, $mNewpass, $mRetype, $mDomain;
+
public function __construct() {
parent::__construct( 'ChangePassword' );
}
@@ -70,8 +73,10 @@ class SpecialChangePassword extends UnlistedSpecialPage {
}
$this->attemptReset( $this->mNewpass, $this->mRetype );
- $this->getOutput()->addWikiMsg( 'resetpass_success' );
- if( !$user->isLoggedIn() ) {
+
+ if( $user->isLoggedIn() ) {
+ $this->doReturnTo();
+ } else {
LoginForm::setLoginToken();
$token = LoginForm::getLoginToken();
$data = array(
@@ -79,17 +84,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
'wpName' => $this->mUserName,
'wpDomain' => $this->mDomain,
'wpLoginToken' => $token,
- 'wpPassword' => $this->mNewpass,
- 'returnto' => $request->getVal( 'returnto' ),
- );
- if( $request->getCheck( 'wpRemember' ) ) {
- $data['wpRemember'] = 1;
- }
+ 'wpPassword' => $request->getVal( 'wpNewPassword' ),
+ ) + $request->getValues( 'wpRemember', 'returnto', 'returntoquery' );
$login = new LoginForm( new FauxRequest( $data, true ) );
$login->setContext( $this->getContext() );
$login->execute( null );
}
- $this->doReturnTo();
+ return;
} catch( PasswordError $e ) {
$this->error( $e->getMessage() );
}
@@ -98,15 +99,20 @@ class SpecialChangePassword extends UnlistedSpecialPage {
}
function doReturnTo() {
- $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) );
+ $request = $this->getRequest();
+ $titleObj = Title::newFromText( $request->getVal( 'returnto' ) );
if ( !$titleObj instanceof Title ) {
$titleObj = Title::newMainPage();
}
- $this->getOutput()->redirect( $titleObj->getFullURL() );
+ $query = $request->getVal( 'returntoquery' );
+ $this->getOutput()->redirect( $titleObj->getFullURL( $query ) );
}
+ /**
+ * @param $msg string
+ */
function error( $msg ) {
- $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) );
+ $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $msg ) );
}
function showForm() {
@@ -142,6 +148,15 @@ class SpecialChangePassword extends UnlistedSpecialPage {
array( 'wpRetype', 'retypenew', 'password', null ),
);
$prettyFields = array_merge( $prettyFields, $extraFields );
+ $hiddenFields = array(
+ 'token' => $user->getEditToken(),
+ 'wpName' => $this->mUserName,
+ 'wpDomain' => $this->mDomain,
+ ) + $this->getRequest()->getValues( 'returnto', 'returntoquery' );
+ $hiddenFieldsStr = '';
+ foreach( $hiddenFields as $fieldname => $fieldvalue ) {
+ $hiddenFieldsStr .= Html::hidden( $fieldname, $fieldvalue ) . "\n";
+ }
$this->getOutput()->addHTML(
Xml::fieldset( $this->msg( 'resetpass_header' )->text() ) .
Xml::openElement( 'form',
@@ -149,10 +164,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
'method' => 'post',
'action' => $this->getTitle()->getLocalUrl(),
'id' => 'mw-resetpass-form' ) ) . "\n" .
- Html::hidden( 'token', $user->getEditToken() ) . "\n" .
- Html::hidden( 'wpName', $this->mUserName ) . "\n" .
- Html::hidden( 'wpDomain', $this->mDomain ) . "\n" .
- Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" .
+ $hiddenFieldsStr .
$this->msg( 'resetpass_text' )->parseAsBlock() . "\n" .
Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" .
$this->pretty( $prettyFields ) . "\n" .
@@ -170,6 +182,10 @@ class SpecialChangePassword extends UnlistedSpecialPage {
);
}
+ /**
+ * @param $fields array
+ * @return string
+ */
function pretty( $fields ) {
$out = '';
foreach ( $fields as $list ) {
@@ -192,7 +208,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
if ( $type != 'text' )
$out .= Xml::label( $this->msg( $label )->text(), $name );
else
- $out .= $this->msg( $label )->escaped();
+ $out .= $this->msg( $label )->escaped();
$out .= "</td>\n";
$out .= "\t<td class='mw-input'>";
$out .= $field;
@@ -206,7 +222,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
* @throws PasswordError when cannot set the new password because requirements not met.
*/
protected function attemptReset( $newpass, $retype ) {
- $user = User::newFromName( $this->mUserName );
+ $isSelf = ( $this->mUserName === $this->getUser()->getName() );
+ if ( $isSelf ) {
+ $user = $this->getUser();
+ } else {
+ $user = User::newFromName( $this->mUserName );
+ }
+
if( !$user || $user->isAnon() ) {
throw new PasswordError( $this->msg( 'nosuchusershort', $this->mUserName )->text() );
}
@@ -227,7 +249,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
throw new PasswordError( $this->msg( $abortMsg )->text() );
}
- if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) {
+ if( !$user->checkTemporaryPassword( $this->mOldpass ) && !$user->checkPassword( $this->mOldpass ) ) {
wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
throw new PasswordError( $this->msg( 'resetpass-wrong-oldpass' )->text() );
}
@@ -240,13 +262,22 @@ class SpecialChangePassword extends UnlistedSpecialPage {
try {
$user->setPassword( $this->mNewpass );
wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) );
- $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
+ $this->mNewpass = $this->mOldpass = $this->mRetype = '';
} catch( PasswordError $e ) {
wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) );
throw new PasswordError( $e->getMessage() );
}
- $user->setCookies();
+ if ( $isSelf ) {
+ // This is needed to keep the user connected since
+ // changing the password also modifies the user's token.
+ $user->setCookies();
+ }
+
$user->saveSettings();
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialComparePages.php b/includes/specials/SpecialComparePages.php
index 9e3c52b9..c3bd3fec 100644
--- a/includes/specials/SpecialComparePages.php
+++ b/includes/specials/SpecialComparePages.php
@@ -106,28 +106,33 @@ class SpecialComparePages extends SpecialPage {
$form->trySubmit();
}
- public static function showDiff( $data, HTMLForm $form ){
+ public static function showDiff( $data, HTMLForm $form ) {
$rev1 = self::revOrTitle( $data['Revision1'], $data['Page1'] );
$rev2 = self::revOrTitle( $data['Revision2'], $data['Page2'] );
if( $rev1 && $rev2 ) {
- $de = new DifferenceEngine( $form->getContext(),
- $rev1,
- $rev2,
- null, // rcid
- ( $data['Action'] == 'purge' ),
- ( $data['Unhide'] == '1' )
- );
- $de->showDiffPage( true );
+ $revision = Revision::newFromId( $rev1 );
+
+ if ( $revision ) { // NOTE: $rev1 was already checked, should exist.
+ $contentHandler = $revision->getContentHandler();
+ $de = $contentHandler->createDifferenceEngine( $form->getContext(),
+ $rev1,
+ $rev2,
+ null, // rcid
+ ( $data['Action'] == 'purge' ),
+ ( $data['Unhide'] == '1' )
+ );
+ $de->showDiffPage( true );
+ }
}
}
public static function revOrTitle( $revision, $title ) {
- if( $revision ){
+ if( $revision ) {
return $revision;
} elseif( $title ) {
$title = Title::newFromText( $title );
- if( $title instanceof Title ){
+ if( $title instanceof Title ) {
return $title->getLatestRevID();
}
}
@@ -158,4 +163,8 @@ class SpecialComparePages extends SpecialPage {
}
return true;
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
diff --git a/includes/specials/SpecialConfirmemail.php b/includes/specials/SpecialConfirmemail.php
index 3e9ce128..078c3865 100644
--- a/includes/specials/SpecialConfirmemail.php
+++ b/includes/specials/SpecialConfirmemail.php
@@ -98,7 +98,7 @@ class EmailConfirmation extends UnlistedSpecialPage {
$out->wrapWikiMsg( "<div class=\"error mw-confirmemail-pending\">\n$1\n</div>", 'confirmemail_pending' );
}
$out->addWikiMsg( 'confirmemail_text' );
- $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl() ) );
+ $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl() ) );
$form .= Html::hidden( 'token', $user->getEditToken() );
$form .= Xml::submitButton( $this->msg( 'confirmemail_send' )->text() );
$form .= Xml::closeElement( 'form' );
@@ -110,7 +110,7 @@ class EmailConfirmation extends UnlistedSpecialPage {
* Attempt to confirm the user's email address and show success or failure
* as needed; if successful, take the user to log in
*
- * @param $code string Confirmation code
+ * @param string $code Confirmation code
*/
function attemptConfirm( $code ) {
$user = User::newFromConfirmationCode( $code );
@@ -145,9 +145,7 @@ class EmailInvalidation extends UnlistedSpecialPage {
function execute( $code ) {
$this->setHeaders();
- if ( wfReadOnly() ) {
- throw new ReadOnlyError;
- }
+ $this->checkReadOnly();
$this->attemptInvalidate( $code );
}
@@ -156,7 +154,7 @@ class EmailInvalidation extends UnlistedSpecialPage {
* Attempt to invalidate the user's email address and show success or failure
* as needed; if successful, link to main page
*
- * @param $code string Confirmation code
+ * @param string $code Confirmation code
*/
function attemptInvalidate( $code ) {
$user = User::newFromConfirmationCode( $code );
diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php
index 54f8e261..b118059c 100644
--- a/includes/specials/SpecialContributions.php
+++ b/includes/specials/SpecialContributions.php
@@ -152,7 +152,7 @@ class SpecialContributions extends SpecialPage {
$apiParams['month'] = $this->opts['month'];
}
- $url = wfScript( 'api' ) . '?' . wfArrayToCGI( $apiParams );
+ $url = wfScript( 'api' ) . '?' . wfArrayToCgi( $apiParams );
$out->redirect( $url, '301' );
return;
@@ -192,7 +192,6 @@ class SpecialContributions extends SpecialPage {
}
$out->preventClickjacking( $pager->getPreventClickjacking() );
-
# Show the appropriate "footer" message - WHOIS tools, etc.
if ( $this->opts['contribs'] == 'newbie' ) {
$message = 'sp-contributions-footer-newbies';
@@ -360,7 +359,7 @@ class SpecialContributions extends SpecialPage {
if ( !isset( $this->opts['target'] ) ) {
$this->opts['target'] = '';
} else {
- $this->opts['target'] = str_replace( '_' , ' ' , $this->opts['target'] );
+ $this->opts['target'] = str_replace( '_', ' ', $this->opts['target'] );
}
if ( !isset( $this->opts['namespace'] ) ) {
@@ -399,7 +398,7 @@ class SpecialContributions extends SpecialPage {
$this->opts['topOnly'] = false;
}
- $form = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'class' => 'mw-contributions-form' ) );
+ $form = Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'class' => 'mw-contributions-form' ) );
# Add hidden params for tracking except for parameters in $skipParameters
$skipParameters = array( 'namespace', 'nsInvert', 'deletedOnly', 'target', 'contribs', 'year', 'month', 'topOnly', 'associated' );
@@ -414,17 +413,17 @@ class SpecialContributions extends SpecialPage {
if ( $tagFilter ) {
$filterSelection =
- Xml::tags( 'td', array( 'class' => 'mw-label' ), array_shift( $tagFilter ) ) .
- Xml::tags( 'td', array( 'class' => 'mw-input' ), implode( '&#160', $tagFilter ) );
+ Html::rawElement( 'td', array( 'class' => 'mw-label' ), array_shift( $tagFilter ) ) .
+ Html::rawElement( 'td', array( 'class' => 'mw-input' ), implode( '&#160', $tagFilter ) );
} else {
- $filterSelection = Xml::tags( 'td', array( 'colspan' => 2 ), '' );
+ $filterSelection = Html::rawElement( 'td', array( 'colspan' => 2 ), '' );
}
- $targetSelection = Xml::tags( 'td', array( 'colspan' => 2 ),
+ $targetSelection = Html::rawElement( 'td', array( 'colspan' => 2 ),
Xml::radioLabel(
$this->msg( 'sp-contributions-newbies' )->text(),
'contribs',
- 'newbie' ,
+ 'newbie',
'newbie',
$this->opts['contribs'] == 'newbie',
array( 'class' => 'mw-input' )
@@ -445,7 +444,7 @@ class SpecialContributions extends SpecialPage {
( $this->opts['target'] ? array() : array( 'autofocus' )
)
) . ' '
- ) ;
+ );
$namespaceSelection =
Xml::tags( 'td', array( 'class' => 'mw-label' ),
@@ -455,7 +454,7 @@ class SpecialContributions extends SpecialPage {
''
)
) .
- Xml::tags( 'td', null,
+ Html::rawElement( 'td', null,
Html::namespaceSelector( array(
'selected' => $this->opts['namespace'],
'all' => '',
@@ -483,10 +482,10 @@ class SpecialContributions extends SpecialPage {
array( 'title' => $this->msg( 'tooltip-namespace_association' )->text(), 'class' => 'mw-input' )
) . '&#160;'
)
- ) ;
+ );
- $extraOptions = Xml::tags( 'td', array( 'colspan' => 2 ),
- Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
+ if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+ $deletedOnlyCheck = Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
$this->msg( 'history-show-deleted' )->text(),
'deletedOnly',
@@ -494,7 +493,13 @@ class SpecialContributions extends SpecialPage {
$this->opts['deletedOnly'],
array( 'class' => 'mw-input' )
)
- ) .
+ );
+ } else {
+ $deletedOnlyCheck = '';
+ }
+
+ $extraOptions = Html::rawElement( 'td', array( 'colspan' => 2 ),
+ $deletedOnlyCheck .
Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
$this->msg( 'sp-contributions-toponly' )->text(),
@@ -504,7 +509,7 @@ class SpecialContributions extends SpecialPage {
array( 'class' => 'mw-input' )
)
)
- ) ;
+ );
$dateSelectionAndSubmit = Xml::tags( 'td', array( 'colspan' => 2 ),
Xml::dateMenu(
@@ -515,36 +520,30 @@ class SpecialContributions extends SpecialPage {
$this->msg( 'sp-contributions-submit' )->text(),
array( 'class' => 'mw-submit' )
)
- ) ;
+ );
$form .=
Xml::fieldset( $this->msg( 'sp-contributions-search' )->text() ) .
- Xml::openElement( 'table', array( 'class' => 'mw-contributions-table' ) ) .
- Xml::openElement( 'tr' ) .
- $targetSelection .
- Xml::closeElement( 'tr' ) .
- Xml::openElement( 'tr' ) .
- $namespaceSelection .
- Xml::closeElement( 'tr' ) .
- Xml::openElement( 'tr' ) .
- $filterSelection .
- Xml::closeElement( 'tr' ) .
- Xml::openElement( 'tr' ) .
- $extraOptions .
- Xml::closeElement( 'tr' ) .
- Xml::openElement( 'tr' ) .
- $dateSelectionAndSubmit .
- Xml::closeElement( 'tr' ) .
- Xml::closeElement( 'table' );
+ Html::rawElement( 'table', array( 'class' => 'mw-contributions-table' ), "\n" .
+ Html::rawElement( 'tr', array(), $targetSelection ) . "\n" .
+ Html::rawElement( 'tr', array(), $namespaceSelection ) . "\n" .
+ Html::rawElement( 'tr', array(), $filterSelection ) . "\n" .
+ Html::rawElement( 'tr', array(), $extraOptions ) . "\n" .
+ Html::rawElement( 'tr', array(), $dateSelectionAndSubmit ) . "\n"
+ );
$explain = $this->msg( 'sp-contributions-explain' );
- if ( $explain->exists() ) {
- $form .= "<p id='mw-sp-contributions-explain'>{$explain}</p>";
+ if ( !$explain->isBlank() ) {
+ $form .= "<p id='mw-sp-contributions-explain'>{$explain->parse()}</p>";
}
$form .= Xml::closeElement( 'fieldset' ) .
Xml::closeElement( 'form' );
return $form;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
/**
@@ -598,7 +597,7 @@ class ContribsPager extends ReverseChronologicalPager {
* This method basically executes the exact same code as the parent class, though with
* a hook added, to allow extentions to add additional queries.
*
- * @param $offset String: index offset, inclusive
+ * @param string $offset index offset, inclusive
* @param $limit Integer: exact query limit
* @param $descending Boolean: query direction, false for ascending, true for descending
* @return ResultWrapper
@@ -631,7 +630,7 @@ class ContribsPager extends ReverseChronologicalPager {
$result = array();
// loop all results and collect them in an array
- foreach ( $data as $j => $query ) {
+ foreach ( $data as $query ) {
foreach ( $query as $i => $row ) {
// use index column as key, allowing us to easily sort in PHP
$result[$row->{$this->getIndexField()} . "-$i"] = $row;
@@ -731,10 +730,10 @@ class ContribsPager extends ReverseChronologicalPager {
}
}
if ( $this->deletedOnly ) {
- $condition[] = "rev_deleted != '0'";
+ $condition[] = 'rev_deleted != 0';
}
if ( $this->topOnly ) {
- $condition[] = "rev_id = page_latest";
+ $condition[] = 'rev_id = page_latest';
}
return array( $tables, $index, $condition, $join_conds );
}
@@ -831,7 +830,7 @@ class ContribsPager extends ReverseChronologicalPager {
*/
wfSuppressWarnings();
$rev = new Revision( $row );
- $validRevision = $rev->getParentId() !== null;
+ $validRevision = (bool) $rev->getId();
wfRestoreWarnings();
if ( $validRevision ) {
@@ -950,8 +949,12 @@ class ContribsPager extends ReverseChronologicalPager {
// Let extensions add data
wfRunHooks( 'ContributionsLineEnding', array( $this, &$ret, $row, &$classes ) );
- $classes = implode( ' ', $classes );
- $ret = "<li class=\"$classes\">$ret</li>\n";
+ if ( $classes === array() && $ret === '' ) {
+ wfDebug( 'Dropping Special:Contribution row that could not be formatted' );
+ $ret = "<!-- Could not format Special:Contribution row. -->\n";
+ } else {
+ $ret = Html::rawElement( 'li', array( 'class' => $classes ), $ret ) . "\n";
+ }
wfProfileOut( __METHOD__ );
return $ret;
diff --git a/includes/specials/SpecialDeadendpages.php b/includes/specials/SpecialDeadendpages.php
index f4904a50..6978d6bb 100644
--- a/includes/specials/SpecialDeadendpages.php
+++ b/includes/specials/SpecialDeadendpages.php
@@ -82,4 +82,8 @@ class DeadendPagesPage extends PageQueryPage {
return array( 'page_title' );
}
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialDeletedContributions.php b/includes/specials/SpecialDeletedContributions.php
index c880b617..e374979e 100644
--- a/includes/specials/SpecialDeletedContributions.php
+++ b/includes/specials/SpecialDeletedContributions.php
@@ -135,7 +135,10 @@ class DeletedContribsPager extends IndexPager {
function formatRow( $row ) {
wfProfileIn( __METHOD__ );
+ $page = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+
$rev = new Revision( array(
+ 'title' => $page,
'id' => $row->ar_rev_id,
'comment' => $row->ar_comment,
'user' => $row->ar_user,
@@ -145,8 +148,6 @@ class DeletedContribsPager extends IndexPager {
'deleted' => $row->ar_deleted,
) );
- $page = Title::makeTitle( $row->ar_namespace, $row->ar_title );
-
$undelete = SpecialPage::getTitleFor( 'Undelete' );
$logs = SpecialPage::getTitleFor( 'Log' );
@@ -167,7 +168,7 @@ class DeletedContribsPager extends IndexPager {
$user = $this->getUser();
- if( $user->isAllowed('deletedtext') ) {
+ if( $user->isAllowed( 'deletedtext' ) ) {
$last = Linker::linkKnown(
$undelete,
$this->messages['diff'],
@@ -260,7 +261,7 @@ class DeletedContributionsPage extends SpecialPage {
* Special page "deleted user contributions".
* Shows a list of the deleted contributions of a user.
*
- * @param $par String: (optional) user name of the user for which to show the contributions
+ * @param string $par (optional) user name of the user for which to show the contributions
*/
function execute( $par ) {
global $wgQueryPageDefaultLimit;
@@ -464,7 +465,7 @@ class DeletedContributionsPage extends SpecialPage {
/**
* Generates the namespace selector form with hidden attributes.
- * @param $options Array: the options to be included.
+ * @param array $options the options to be included.
* @return string
*/
function getForm( $options ) {
@@ -474,7 +475,7 @@ class DeletedContributionsPage extends SpecialPage {
if ( !isset( $options['target'] ) ) {
$options['target'] = '';
} else {
- $options['target'] = str_replace( '_' , ' ' , $options['target'] );
+ $options['target'] = str_replace( '_', ' ', $options['target'] );
}
if ( !isset( $options['namespace'] ) ) {
@@ -498,7 +499,7 @@ class DeletedContributionsPage extends SpecialPage {
$f .= "\t" . Html::hidden( $name, $value ) . "\n";
}
- $f .= Xml::openElement( 'fieldset' ) .
+ $f .= Xml::openElement( 'fieldset' ) .
Xml::element( 'legend', array(), $this->msg( 'sp-contributions-search' )->text() ) .
Xml::tags( 'label', array( 'for' => 'target' ), $this->msg( 'sp-contributions-username' )->parse() ) . ' ' .
Html::input( 'target', $options['target'], 'text', array(
@@ -521,4 +522,8 @@ class DeletedContributionsPage extends SpecialPage {
Xml::closeElement( 'form' );
return $f;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialDisambiguations.php b/includes/specials/SpecialDisambiguations.php
index 48180a77..2126ca52 100644
--- a/includes/specials/SpecialDisambiguations.php
+++ b/includes/specials/SpecialDisambiguations.php
@@ -59,20 +59,20 @@ class DisambiguationsPage extends QueryPage {
if( $dp->getNamespace() != NS_TEMPLATE ) {
# @todo FIXME: We assume the disambiguation message is a template but
# the page can potentially be from another namespace :/
- wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
+ wfDebug( "Mediawiki:disambiguationspage message does not refer to a template!\n" );
}
$linkBatch->addObj( $dp );
} else {
# Get all the templates linked from the Mediawiki:Disambiguationspage
$disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' );
$res = $dbr->select(
- array('pagelinks', 'page'),
+ array( 'pagelinks', 'page' ),
'pl_title',
- array('page_id = pl_from',
+ array( 'page_id = pl_from',
'pl_namespace' => NS_TEMPLATE,
'page_namespace' => $disPageObj->getNamespace(),
- 'page_title' => $disPageObj->getDBkey()),
- __METHOD__ );
+ 'page_title' => $disPageObj->getDBkey()
+ ), __METHOD__ );
foreach ( $res as $row ) {
$linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title ));
@@ -158,4 +158,8 @@ class DisambiguationsPage extends QueryPage {
return "$from $edit $arr $to";
}
+
+ protected function getGroupName() {
+ return 'pages';
+ }
}
diff --git a/includes/specials/SpecialDoubleRedirects.php b/includes/specials/SpecialDoubleRedirects.php
index 5864ca9f..5a5d749c 100644
--- a/includes/specials/SpecialDoubleRedirects.php
+++ b/includes/specials/SpecialDoubleRedirects.php
@@ -33,9 +33,17 @@ class DoubleRedirectsPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
- function sortDescending() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function sortDescending() {
+ return false;
+ }
function getPageHeader() {
return $this->msg( 'doubleredirectstext' )->parseAsBlock();
@@ -43,23 +51,45 @@ class DoubleRedirectsPage extends QueryPage {
function reallyGetQueryInfo( $namespace = null, $title = null ) {
$limitToTitle = !( $namespace === null && $title === null );
+ $dbr = wfGetDB( DB_SLAVE );
$retval = array (
- 'tables' => array ( 'ra' => 'redirect',
- 'rb' => 'redirect', 'pa' => 'page',
- 'pb' => 'page', 'pc' => 'page' ),
- 'fields' => array ( 'namespace' => 'pa.page_namespace',
- 'title' => 'pa.page_title',
- 'value' => 'pa.page_title',
- 'nsb' => 'pb.page_namespace',
- 'tb' => 'pb.page_title',
- 'nsc' => 'pc.page_namespace',
- 'tc' => 'pc.page_title' ),
- 'conds' => array ( 'ra.rd_from = pa.page_id',
- 'pb.page_namespace = ra.rd_namespace',
- 'pb.page_title = ra.rd_title',
- 'rb.rd_from = pb.page_id',
- 'pc.page_namespace = rb.rd_namespace',
- 'pc.page_title = rb.rd_title' )
+ 'tables' => array (
+ 'ra' => 'redirect',
+ 'rb' => 'redirect',
+ 'pa' => 'page',
+ 'pb' => 'page'
+ ),
+ 'fields' => array(
+ 'namespace' => 'pa.page_namespace',
+ 'title' => 'pa.page_title',
+ 'value' => 'pa.page_title',
+
+ 'nsb' => 'pb.page_namespace',
+ 'tb' => 'pb.page_title',
+
+ // Select fields from redirect instead of page. Because there may
+ // not actually be a page table row for this target (e.g. for interwiki redirects)
+ 'nsc' => 'rb.rd_namespace',
+ 'tc' => 'rb.rd_title',
+ 'iwc' => 'rb.rd_interwiki',
+ ),
+ 'conds' => array(
+ 'ra.rd_from = pa.page_id',
+
+ // Filter out redirects where the target goes interwiki (bug 40353).
+ // This isn't an optimization, it is required for correct results,
+ // otherwise a non-double redirect like Bar -> w:Foo will show up
+ // like "Bar -> Foo -> w:Foo".
+
+ // Need to check both NULL and "" for some reason,
+ // apparently either can be stored for non-iw entries.
+ 'ra.rd_interwiki IS NULL OR ra.rd_interwiki = ' . $dbr->addQuotes( '' ),
+
+ 'pb.page_namespace = ra.rd_namespace',
+ 'pb.page_title = ra.rd_title',
+
+ 'rb.rd_from = pb.page_id',
+ )
);
if ( $limitToTitle ) {
$retval['conds']['pa.page_namespace'] = $namespace;
@@ -79,11 +109,16 @@ class DoubleRedirectsPage extends QueryPage {
function formatResult( $skin, $result ) {
$titleA = Title::makeTitle( $result->namespace, $result->title );
+ // If only titleA is in the query, it means this came from
+ // querycache (which only saves 3 columns).
+ // That does save the bulk of the query cost, but now we need to
+ // get a little more detail about each individual entry quickly
+ // using the filter of reallyGetQueryInfo.
if ( $result && !isset( $result->nsb ) ) {
$dbr = wfGetDB( DB_SLAVE );
$qi = $this->reallyGetQueryInfo( $result->namespace,
$result->title );
- $res = $dbr->select($qi['tables'], $qi['fields'],
+ $res = $dbr->select( $qi['tables'], $qi['fields'],
$qi['conds'], __METHOD__ );
if ( $res ) {
$result = $dbr->fetchObject( $res );
@@ -94,7 +129,7 @@ class DoubleRedirectsPage extends QueryPage {
}
$titleB = Title::makeTitle( $result->nsb, $result->tb );
- $titleC = Title::makeTitle( $result->nsc, $result->tc );
+ $titleC = Title::makeTitle( $result->nsc, $result->tc, '', $result->iwc );
$linkA = Linker::linkKnown(
$titleA,
@@ -127,4 +162,8 @@ class DoubleRedirectsPage extends QueryPage {
return( "{$linkA} {$edit} {$arr} {$linkB} {$arr} {$linkC}" );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialEditWatchlist.php b/includes/specials/SpecialEditWatchlist.php
index 23cd9aa6..d2838e01 100644
--- a/includes/specials/SpecialEditWatchlist.php
+++ b/includes/specials/SpecialEditWatchlist.php
@@ -49,7 +49,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
private $badItems = array();
- public function __construct(){
+ public function __construct() {
parent::__construct( 'EditWatchlist' );
}
@@ -77,6 +77,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
}
$this->checkPermissions();
+ $this->checkReadOnly();
$this->outputHeader();
@@ -85,9 +86,9 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
# B/C: $mode used to be waaay down the parameter list, and the first parameter
# was $wgUser
- if( $mode instanceof User ){
+ if( $mode instanceof User ) {
$args = func_get_args();
- if( count( $args >= 4 ) ){
+ if( count( $args >= 4 ) ) {
$mode = $args[3];
}
}
@@ -101,7 +102,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
case self::EDIT_RAW:
$out->setPageTitle( $this->msg( 'watchlistedit-raw-title' ) );
$form = $this->getRawForm();
- if( $form->show() ){
+ if( $form->show() ) {
$out->addHTML( $this->successMessage );
$out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
}
@@ -111,7 +112,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
default:
$out->setPageTitle( $this->msg( 'watchlistedit-normal-title' ) );
$form = $this->getNormalForm();
- if( $form->show() ){
+ if( $form->show() ) {
$out->addHTML( $this->successMessage );
$out->addReturnTo( SpecialPage::getTitleFor( 'Watchlist' ) );
} elseif ( $this->toc !== false ) {
@@ -153,7 +154,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
return array_unique( $list );
}
- public function submitRaw( $data ){
+ public function submitRaw( $data ) {
$wanted = $this->extractTitles( $data['Titles'] );
$current = $this->getWatchlist();
@@ -164,7 +165,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
$this->unwatchTitles( $toUnwatch );
$this->getUser()->invalidateCache();
- if( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ){
+ if( count( $toWatch ) > 0 || count( $toUnwatch ) > 0 ) {
$this->successMessage = $this->msg( 'watchlistedit-raw-done' )->parse();
} else {
return false;
@@ -185,7 +186,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
$this->clearWatchlist();
$this->getUser()->invalidateCache();
- if( count( $current ) > 0 ){
+ if( count( $current ) > 0 ) {
$this->successMessage = $this->msg( 'watchlistedit-raw-done' )->parse();
} else {
return false;
@@ -204,7 +205,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
* $titles can be an array of strings or Title objects; the former
* is preferred, since Titles are very memory-heavy
*
- * @param $titles array of strings, or Title objects
+ * @param array $titles of strings, or Title objects
* @param $output String
*/
private function showTitles( $titles, &$output ) {
@@ -289,7 +290,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
$res = $dbr->select(
array( 'watchlist' ),
- array( 'wl_namespace', 'wl_title' ),
+ array( 'wl_namespace', 'wl_title' ),
array( 'wl_user' => $this->getUser()->getId() ),
__METHOD__,
array( 'ORDER BY' => array( 'wl_namespace', 'wl_title' ) )
@@ -312,7 +313,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
*
* @param Title $title
* @param int $namespace
- * @param String $dbKey
+ * @param string $dbKey
* @return bool: Whether this item is valid
*/
private function checkTitle( $title, $namespace, $dbKey ) {
@@ -381,7 +382,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
* $titles can be an array of strings or Title objects; the former
* is preferred, since Titles are very memory-heavy
*
- * @param $titles Array of strings, or Title objects
+ * @param array $titles of strings, or Title objects
*/
private function watchTitles( $titles ) {
$dbw = wfGetDB( DB_MASTER );
@@ -393,13 +394,13 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
if( $title instanceof Title ) {
$rows[] = array(
'wl_user' => $this->getUser()->getId(),
- 'wl_namespace' => ( $title->getNamespace() & ~1 ),
+ 'wl_namespace' => MWNamespace::getSubject( $title->getNamespace() ),
'wl_title' => $title->getDBkey(),
'wl_notificationtimestamp' => null,
);
$rows[] = array(
'wl_user' => $this->getUser()->getId(),
- 'wl_namespace' => ( $title->getNamespace() | 1 ),
+ 'wl_namespace' => MWNamespace::getTalk( $title->getNamespace() ),
'wl_title' => $title->getDBkey(),
'wl_notificationtimestamp' => null,
);
@@ -414,7 +415,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
* $titles can be an array of strings or Title objects; the former
* is preferred, since Titles are very memory-heavy
*
- * @param $titles Array of strings, or Title objects
+ * @param array $titles of strings, or Title objects
*/
private function unwatchTitles( $titles ) {
$dbw = wfGetDB( DB_MASTER );
@@ -427,7 +428,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
'watchlist',
array(
'wl_user' => $this->getUser()->getId(),
- 'wl_namespace' => ( $title->getNamespace() & ~1 ),
+ 'wl_namespace' => MWNamespace::getSubject( $title->getNamespace() ),
'wl_title' => $title->getDBkey(),
),
__METHOD__
@@ -436,7 +437,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
'watchlist',
array(
'wl_user' => $this->getUser()->getId(),
- 'wl_namespace' => ( $title->getNamespace() | 1 ),
+ 'wl_namespace' => MWNamespace::getTalk( $title->getNamespace() ),
'wl_title' => $title->getDBkey(),
),
__METHOD__
@@ -470,26 +471,26 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
*
* @return HTMLForm
*/
- protected function getNormalForm(){
+ protected function getNormalForm() {
global $wgContLang;
$fields = array();
$count = 0;
- foreach( $this->getWatchlistInfo() as $namespace => $pages ){
+ foreach( $this->getWatchlistInfo() as $namespace => $pages ) {
if ( $namespace >= 0 ) {
- $fields['TitlesNs'.$namespace] = array(
+ $fields['TitlesNs' . $namespace] = array(
'class' => 'EditWatchlistCheckboxSeriesField',
'options' => array(),
'section' => "ns$namespace",
);
}
- foreach( array_keys( $pages ) as $dbkey ){
+ foreach( array_keys( $pages ) as $dbkey ) {
$title = Title::makeTitleSafe( $namespace, $dbkey );
if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
$text = $this->buildRemoveLine( $title );
- $fields['TitlesNs'.$namespace]['options'][$text] = htmlspecialchars( $title->getPrefixedText() );
+ $fields['TitlesNs' . $namespace]['options'][$text] = $title->getPrefixedText();
$count++;
}
}
@@ -519,7 +520,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
$form->setTitle( $this->getTitle() );
$form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
# Used message keys: 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
- $form->setSubmitTooltip('watchlistedit-normal-submit');
+ $form->setSubmitTooltip( 'watchlistedit-normal-submit' );
$form->setWrapperLegendMsg( 'watchlistedit-normal-legend' );
$form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() );
$form->setSubmitCallback( array( $this, 'submitNormal' ) );
@@ -564,7 +565,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
*
* @return HTMLForm
*/
- protected function getRawForm(){
+ protected function getRawForm() {
$titles = implode( $this->getWatchlist(), "\n" );
$fields = array(
'Titles' => array(
@@ -577,7 +578,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
$form->setTitle( $this->getTitle( 'raw' ) );
$form->setSubmitTextMsg( 'watchlistedit-raw-submit' );
# Used message keys: 'accesskey-watchlistedit-raw-submit', 'tooltip-watchlistedit-raw-submit'
- $form->setSubmitTooltip('watchlistedit-raw-submit');
+ $form->setSubmitTooltip( 'watchlistedit-raw-submit' );
$form->setWrapperLegendMsg( 'watchlistedit-raw-legend' );
$form->addHeaderText( $this->msg( 'watchlistedit-raw-explain' )->parse() );
$form->setSubmitCallback( array( $this, 'submitRaw' ) );
@@ -648,7 +649,7 @@ class WatchlistEditor extends SpecialEditWatchlist {}
* Extend HTMLForm purely so we can have a more sane way of getting the section headers
*/
class EditWatchlistNormalHTMLForm extends HTMLForm {
- public function getLegend( $namespace ){
+ public function getLegend( $namespace ) {
$namespace = substr( $namespace, 2 );
return $namespace == NS_MAIN
? $this->msg( 'blanknamespace' )->escaped()
@@ -667,8 +668,8 @@ class EditWatchlistCheckboxSeriesField extends HTMLMultiSelectField {
* form is open (bug 32126), but we know that invalid items will
* be harmless so we can override it here.
*
- * @param $value String the value the field was submitted with
- * @param $alldata Array the data collected from the form
+ * @param string $value the value the field was submitted with
+ * @param array $alldata the data collected from the form
* @return Mixed Bool true on success, or String error to display.
*/
function validate( $value, $alldata ) {
diff --git a/includes/specials/SpecialEmailuser.php b/includes/specials/SpecialEmailuser.php
index 4d875e6e..b5ad589e 100644
--- a/includes/specials/SpecialEmailuser.php
+++ b/includes/specials/SpecialEmailuser.php
@@ -139,7 +139,8 @@ class SpecialEmailUser extends UnlistedSpecialPage {
$this->mTargetObj = $ret;
$form = new HTMLForm( $this->getFormFields(), $this->getContext() );
- $form->addPreText( $this->msg( 'emailpagetext' )->parse() );
+ // By now we are supposed to be sure that $this->mTarget is a user name
+ $form->addPreText( $this->msg( 'emailpagetext', $this->mTarget )->parse() );
$form->setSubmitTextMsg( 'emailsend' );
$form->setTitle( $this->getTitle() );
$form->setSubmitCallback( array( __CLASS__, 'uiSubmit' ) );
@@ -162,7 +163,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
/**
* Validate target User
*
- * @param $target String: target user name
+ * @param string $target target user name
* @return User object on success or a string on error
*/
public static function getTarget( $target ) {
@@ -190,7 +191,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
* Check whether a user is allowed to send email
*
* @param $user User object
- * @param $editToken String: edit token
+ * @param string $editToken edit token
* @return null on success or string on error
*/
public static function getPermissionsError( $user, $editToken ) {
@@ -230,7 +231,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
/**
* Form to ask for target user name.
*
- * @param $name String: user name submitted.
+ * @param string $name user name submitted.
* @return String: form asking for user name.
*/
protected function userForm( $name ) {
@@ -336,4 +337,8 @@ class SpecialEmailUser extends UnlistedSpecialPage {
return $status;
}
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialExport.php b/includes/specials/SpecialExport.php
index b4294b32..7abfefe2 100644
--- a/includes/specials/SpecialExport.php
+++ b/includes/specials/SpecialExport.php
@@ -80,7 +80,7 @@ class SpecialExport extends SpecialPage {
$page = $request->getText( 'pages' );
$nsindex = $request->getText( 'nsindex', '' );
- if ( strval( $nsindex ) !== '' ) {
+ if ( strval( $nsindex ) !== '' ) {
/**
* Same implementation as above, so same @todo
*/
@@ -124,7 +124,7 @@ class SpecialExport extends SpecialPage {
if ( $this->curonly ) {
$history = WikiExporter::CURRENT;
} elseif ( !$historyCheck ) {
- if ( $limit > 0 && ($wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
+ if ( $limit > 0 && ( $wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
$history['limit'] = $limit;
}
if ( !is_null( $offset ) ) {
@@ -161,7 +161,7 @@ class SpecialExport extends SpecialPage {
$list_authors = $request->getCheck( 'listauthors' );
if ( !$this->curonly || !$wgExportAllowListContributors ) {
- $list_authors = false ;
+ $list_authors = false;
}
if ( $this->doExport ) {
@@ -272,7 +272,7 @@ class SpecialExport extends SpecialPage {
/**
* Do the actual page exporting
*
- * @param $page String: user input on what page(s) to export
+ * @param string $page user input on what page(s) to export
* @param $history Mixed: one of the WikiExporter history export constants
* @param $list_authors Boolean: Whether to add distinct author list (when
* not returning full history)
@@ -286,7 +286,7 @@ class SpecialExport extends SpecialPage {
} else {
$pageSet = array(); // Inverted index of all pages to look up
-
+
// Split up and normalize input
foreach( explode( "\n", $page ) as $pageName ) {
$pageName = trim( $pageName );
@@ -339,7 +339,7 @@ class SpecialExport extends SpecialPage {
// This might take a while... :D
wfSuppressWarnings();
- set_time_limit(0);
+ set_time_limit( 0 );
wfRestoreWarnings();
}
@@ -405,7 +405,7 @@ class SpecialExport extends SpecialPage {
foreach ( $res as $row ) {
$n = $row->page_title;
- if ($row->page_namespace) {
+ if ( $row->page_namespace ) {
$ns = $wgContLang->getNsText( $row->page_namespace );
$n = $ns . ':' . $n;
}
@@ -561,4 +561,7 @@ class SpecialExport extends SpecialPage {
return $pageSet;
}
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
diff --git a/includes/specials/SpecialFewestrevisions.php b/includes/specials/SpecialFewestrevisions.php
index 7e4bc9ce..5b7f353d 100644
--- a/includes/specials/SpecialFewestrevisions.php
+++ b/includes/specials/SpecialFewestrevisions.php
@@ -60,7 +60,6 @@ class FewestrevisionsPage extends QueryPage {
);
}
-
function sortDescending() {
return false;
}
@@ -94,4 +93,8 @@ class FewestrevisionsPage extends QueryPage {
return $this->getLanguage()->specialList( $plink, $nlink );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialFileDuplicateSearch.php b/includes/specials/SpecialFileDuplicateSearch.php
index ccf8ba17..3fe64e6f 100644
--- a/includes/specials/SpecialFileDuplicateSearch.php
+++ b/includes/specials/SpecialFileDuplicateSearch.php
@@ -40,9 +40,17 @@ class FileDuplicateSearchPage extends QueryPage {
parent::__construct( $name );
}
- function isSyndicated() { return false; }
- function isCacheable() { return false; }
- function isCached() { return false; }
+ function isSyndicated() {
+ return false;
+ }
+
+ function isCacheable() {
+ return false;
+ }
+
+ function isCached() {
+ return false;
+ }
function linkParameters() {
return array( 'filename' => $this->filename );
@@ -59,7 +67,7 @@ class FileDuplicateSearchPage extends QueryPage {
/**
*
- * @param $dupes Array of File objects
+ * @param array $dupes of File objects
*/
function showList( $dupes ) {
$html = array();
@@ -93,7 +101,7 @@ class FileDuplicateSearchPage extends QueryPage {
$this->setHeaders();
$this->outputHeader();
- $this->filename = isset( $par ) ? $par : $this->getRequest()->getText( 'filename' );
+ $this->filename = isset( $par ) ? $par : $this->getRequest()->getText( 'filename' );
$this->file = null;
$this->hash = '';
$title = Title::newFromText( $this->filename, NS_FILE );
@@ -106,7 +114,7 @@ class FileDuplicateSearchPage extends QueryPage {
# Create the input form
$out->addHTML(
Xml::openElement( 'form', array( 'id' => 'fileduplicatesearch', 'method' => 'get', 'action' => $wgScript ) ) .
- Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ) .
+ Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) .
Xml::openElement( 'fieldset' ) .
Xml::element( 'legend', null, $this->msg( 'fileduplicatesearch-legend' )->text() ) .
Xml::inputLabel( $this->msg( 'fileduplicatesearch-filename' )->text(), 'filename', 'filename', 50, $this->filename ) . ' ' .
@@ -207,4 +215,8 @@ class FileDuplicateSearchPage extends QueryPage {
return "$plink . . $user . . $time";
}
+
+ protected function getGroupName() {
+ return 'media';
+ }
}
diff --git a/includes/specials/SpecialFilepath.php b/includes/specials/SpecialFilepath.php
index e0866504..bbcced26 100644
--- a/includes/specials/SpecialFilepath.php
+++ b/includes/specials/SpecialFilepath.php
@@ -47,7 +47,7 @@ class SpecialFilepath extends SpecialPage {
$file = wfFindFile( $title );
if ( $file && $file->exists() ) {
- // Default behaviour: Use the direct link to the file.
+ // Default behavior: Use the direct link to the file.
$url = $file->getURL();
$width = $request->getInt( 'width', -1 );
$height = $request->getInt( 'height', -1 );
@@ -86,4 +86,8 @@ class SpecialFilepath extends SpecialPage {
Html::closeElement( 'form' )
);
}
+
+ protected function getGroupName() {
+ return 'media';
+ }
}
diff --git a/includes/specials/SpecialImport.php b/includes/specials/SpecialImport.php
index 362fc5cf..aa56041b 100644
--- a/includes/specials/SpecialImport.php
+++ b/includes/specials/SpecialImport.php
@@ -101,7 +101,7 @@ class SpecialImport extends SpecialPage {
$this->logcomment = $request->getText( 'log-comment' );
$this->pageLinkDepth = $wgExportMaxLinkDepth == 0 ? 0 : $request->getIntOrNull( 'pagelink-depth' );
- $this->rootpage = $request->getText( 'rootpage' );
+ $this->rootpage = $request->getText( 'rootpage' );
$user = $this->getUser();
if ( !$user->matchEditToken( $request->getVal( 'editToken' ) ) ) {
@@ -114,7 +114,7 @@ class SpecialImport extends SpecialPage {
throw new PermissionsError( 'importupload' );
}
} elseif ( $sourceName == "interwiki" ) {
- if( !$user->isAllowed( 'import' ) ){
+ if( !$user->isAllowed( 'import' ) ) {
throw new PermissionsError( 'import' );
}
$this->interwiki = $request->getVal( 'interwiki' );
@@ -153,7 +153,7 @@ class SpecialImport extends SpecialPage {
$out->addWikiMsg( "importstart" );
- $reporter = new ImportReporter( $importer, $isUpload, $this->interwiki , $this->logcomment);
+ $reporter = new ImportReporter( $importer, $isUpload, $this->interwiki, $this->logcomment );
$reporter->setContext( $this->getContext() );
$exception = false;
@@ -194,14 +194,14 @@ class SpecialImport extends SpecialPage {
$this->msg( 'importtext' )->parseAsBlock() .
Html::hidden( 'action', 'submit' ) .
Html::hidden( 'source', 'upload' ) .
- Xml::openElement( 'table', array( 'id' => 'mw-import-table' ) ) .
+ Xml::openElement( 'table', array( 'id' => 'mw-import-table-upload' ) ) .
"<tr>
<td class='mw-label'>" .
Xml::label( $this->msg( 'import-upload-filename' )->text(), 'xmlimport' ) .
"</td>
<td class='mw-input'>" .
- Xml::input( 'xmlimport', 50, '', array( 'type' => 'file' ) ) . ' ' .
+ Html::input( 'xmlimport', '', 'file', array( 'id' => 'xmlimport' ) ) . ' ' .
"</td>
</tr>
<tr>
@@ -215,11 +215,11 @@ class SpecialImport extends SpecialPage {
</tr>
<tr>
<td class='mw-label'>" .
- Xml::label( $this->msg( 'import-interwiki-rootpage' )->text(), 'mw-interwiki-rootpage' ) .
+ Xml::label( $this->msg( 'import-interwiki-rootpage' )->text(), 'mw-interwiki-rootpage-upload' ) .
"</td>
<td class='mw-input'>" .
Xml::input( 'rootpage', 50, $this->rootpage,
- array( 'id' => 'mw-interwiki-rootpage', 'type' => 'text' ) ) . ' ' .
+ array( 'id' => 'mw-interwiki-rootpage-upload', 'type' => 'text' ) ) . ' ' .
"</td>
</tr>
<tr>
@@ -260,13 +260,13 @@ class SpecialImport extends SpecialPage {
Html::hidden( 'action', 'submit' ) .
Html::hidden( 'source', 'interwiki' ) .
Html::hidden( 'editToken', $user->getEditToken() ) .
- Xml::openElement( 'table', array( 'id' => 'mw-import-table' ) ) .
+ Xml::openElement( 'table', array( 'id' => 'mw-import-table-interwiki' ) ) .
"<tr>
<td class='mw-label'>" .
Xml::label( $this->msg( 'import-interwiki-source' )->text(), 'interwiki' ) .
"</td>
<td class='mw-input'>" .
- Xml::openElement( 'select', array( 'name' => 'interwiki' ) )
+ Xml::openElement( 'select', array( 'name' => 'interwiki', 'id' => 'interwiki' ) )
);
foreach( $wgImportSources as $prefix ) {
$selected = ( $this->interwiki === $prefix ) ? ' selected="selected"' : '';
@@ -275,7 +275,7 @@ class SpecialImport extends SpecialPage {
$out->addHTML(
Xml::closeElement( 'select' ) .
- Xml::input( 'frompage', 50, $this->frompage ) .
+ Xml::input( 'frompage', 50, $this->frompage, array( 'id' => 'frompage' ) ) .
"</td>
</tr>
<tr>
@@ -321,11 +321,11 @@ class SpecialImport extends SpecialPage {
</tr>
<tr>
<td class='mw-label'>" .
- Xml::label( $this->msg( 'import-interwiki-rootpage' )->text(), 'mw-interwiki-rootpage' ) .
+ Xml::label( $this->msg( 'import-interwiki-rootpage' )->text(), 'mw-interwiki-rootpage-interwiki' ) .
"</td>
<td class='mw-input'>" .
Xml::input( 'rootpage', 50, $this->rootpage,
- array( 'id' => 'mw-interwiki-rootpage', 'type' => 'text' ) ) . ' ' .
+ array( 'id' => 'mw-interwiki-rootpage-interwiki', 'type' => 'text' ) ) . ' ' .
"</td>
</tr>
<tr>
@@ -341,6 +341,10 @@ class SpecialImport extends SpecialPage {
);
}
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
/**
@@ -353,7 +357,7 @@ class ImportReporter extends ContextSource {
private $mOriginalPageOutCallback = null;
private $mLogItemCount = 0;
- function __construct( $importer, $upload, $interwiki , $reason=false ) {
+ function __construct( $importer, $upload, $interwiki, $reason = false ) {
$this->mOriginalPageOutCallback =
$importer->setPageOutCallback( array( $this, 'reportPage' ) );
$this->mOriginalLogCallback =
@@ -410,7 +414,7 @@ class ImportReporter extends ContextSource {
$detail = $this->msg( 'import-logentry-upload-detail' )->numParams(
$successCount )->inContentLanguage()->text();
if ( $this->reason ) {
- $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+ $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
}
$log->addEntry( 'upload', $title, $detail );
} else {
@@ -419,7 +423,7 @@ class ImportReporter extends ContextSource {
$detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
$successCount )->params( $interwiki )->inContentLanguage()->text();
if ( $this->reason ) {
- $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+ $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
}
$log->addEntry( 'interwiki', $title, $detail );
}
@@ -428,7 +432,7 @@ class ImportReporter extends ContextSource {
$dbw = wfGetDB( DB_MASTER );
$latest = $title->getLatestRevID();
$nullRevision = Revision::newNullRevision( $dbw, $title->getArticleID(), $comment, true );
- if (!is_null($nullRevision)) {
+ if ( !is_null( $nullRevision ) ) {
$nullRevision->insertOn( $dbw );
$page = WikiPage::factory( $title );
# Update page record
diff --git a/includes/specials/SpecialJavaScriptTest.php b/includes/specials/SpecialJavaScriptTest.php
index c217eccb..d204d50c 100644
--- a/includes/specials/SpecialJavaScriptTest.php
+++ b/includes/specials/SpecialJavaScriptTest.php
@@ -40,19 +40,11 @@ class SpecialJavaScriptTest extends SpecialPage {
}
public function execute( $par ) {
- global $wgEnableJavaScriptTest;
-
$out = $this->getOutput();
$this->setHeaders();
$out->disallowUserJs();
- // Abort early if we're disabled
- if ( $wgEnableJavaScriptTest !== true ) {
- $out->addWikiMsg( 'javascripttest-disabled' );
- return;
- }
-
$out->addModules( 'mediawiki.special.javaScriptTest' );
// Determine framework
@@ -110,8 +102,9 @@ class SpecialJavaScriptTest extends SpecialPage {
* Function to wrap the summary.
* It must be given a valid state as a second parameter or an exception will
* be thrown.
- * @param $html String: The raw HTML.
- * @param $state String: State, one of 'noframework', 'unknownframework' or 'frameworkfound'
+ * @param string $html The raw HTML.
+ * @param string $state State, one of 'noframework', 'unknownframework' or 'frameworkfound'
+ * @throws MWException
* @return string
*/
private function wrapSummaryHtml( $html, $state ) {
@@ -165,9 +158,7 @@ HTML;
$out->addJsConfigVars( 'QUnitTestSwarmInjectJSPath', $wgJavaScriptTestConfig['qunit']['testswarm-injectjs'] );
}
- public function isListed(){
- global $wgEnableJavaScriptTest;
- return $wgEnableJavaScriptTest === true;
+ protected function getGroupName() {
+ return 'other';
}
-
}
diff --git a/includes/specials/SpecialLinkSearch.php b/includes/specials/SpecialLinkSearch.php
index 0810ee77..030416fb 100644
--- a/includes/specials/SpecialLinkSearch.php
+++ b/includes/specials/SpecialLinkSearch.php
@@ -22,7 +22,6 @@
* @author Brion Vibber
*/
-
/**
* Special:LinkSearch to search the external-links table.
* @ingroup SpecialPage
@@ -43,7 +42,7 @@ class LinkSearchPage extends QueryPage {
}
function execute( $par ) {
- global $wgUrlProtocols, $wgMiserMode;
+ global $wgUrlProtocols, $wgMiserMode, $wgScript;
$this->setHeaders();
$this->outputHeader();
@@ -64,15 +63,15 @@ class LinkSearchPage extends QueryPage {
$target2 = $target;
$protocol = '';
- $pr_sl = strpos($target2, '//' );
- $pr_cl = strpos($target2, ':' );
+ $pr_sl = strpos( $target2, '//' );
+ $pr_cl = strpos( $target2, ':' );
if ( $pr_sl ) {
// For protocols with '//'
- $protocol = substr( $target2, 0 , $pr_sl+2 );
- $target2 = substr( $target2, $pr_sl+2 );
+ $protocol = substr( $target2, 0, $pr_sl + 2 );
+ $target2 = substr( $target2, $pr_sl + 2 );
} elseif ( !$pr_sl && $pr_cl ) {
// For protocols without '//' like 'mailto:'
- $protocol = substr( $target2, 0 , $pr_cl+1 );
+ $protocol = substr( $target2, 0, $pr_cl + 1 );
$target2 = substr( $target2, $pr_cl+1 );
} elseif ( $protocol == '' && $target2 != '' ) {
// default
@@ -84,12 +83,16 @@ class LinkSearchPage extends QueryPage {
$protocol = '';
}
- $out->addWikiMsg( 'linksearch-text', '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>' );
- $s = Xml::openElement( 'form', array( 'id' => 'mw-linksearch-form', 'method' => 'get', 'action' => $GLOBALS['wgScript'] ) ) .
- Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ) .
- '<fieldset>' .
- Xml::element( 'legend', array(), $this->msg( 'linksearch' )->text() ) .
- Xml::inputLabel( $this->msg( 'linksearch-pat' )->text(), 'target', 'target', 50, $target ) . ' ';
+ $out->addWikiMsg(
+ 'linksearch-text',
+ '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>',
+ count( $protocols_list )
+ );
+ $s = Html::openElement( 'form', array( 'id' => 'mw-linksearch-form', 'method' => 'get', 'action' => $wgScript ) ) . "\n" .
+ Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n" .
+ Html::openElement( 'fieldset' ) . "\n" .
+ Html::element( 'legend', array(), $this->msg( 'linksearch' )->text() ) . "\n" .
+ Xml::inputLabel( $this->msg( 'linksearch-pat' )->text(), 'target', 'target', 50, $target ) . "\n";
if ( !$wgMiserMode ) {
$s .= Html::namespaceSelector(
array(
@@ -103,9 +106,9 @@ class LinkSearchPage extends QueryPage {
)
);
}
- $s .= Xml::submitButton( $this->msg( 'linksearch-ok' )->text() ) .
- '</fieldset>' .
- Xml::closeElement( 'form' );
+ $s .= Xml::submitButton( $this->msg( 'linksearch-ok' )->text() ) . "\n" .
+ Html::closeElement( 'fieldset' ) . "\n" .
+ Html::closeElement( 'form' ) . "\n";
$out->addHTML( $s );
if( $target != '' ) {
@@ -134,10 +137,10 @@ class LinkSearchPage extends QueryPage {
*/
static function mungeQuery( $query, $prot ) {
$field = 'el_index';
- $rv = LinkFilter::makeLikeArray( $query , $prot );
+ $rv = LinkFilter::makeLikeArray( $query, $prot );
if ( $rv === false ) {
// LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
- if (preg_match('/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query)) {
+ if ( preg_match( '/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query ) ) {
$dbr = wfGetDB( DB_SLAVE );
$rv = array( $prot . rtrim( $query, " \t*" ), $dbr->anyString() );
$field = 'el_to';
@@ -197,7 +200,7 @@ class LinkSearchPage extends QueryPage {
* Override to check query validity.
*/
function doQuery( $offset = false, $limit = false ) {
- list( $this->mMungedQuery, ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
+ list( $this->mMungedQuery, ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
if( $this->mMungedQuery === false ) {
$this->getOutput()->addWikiMsg( 'linksearch-error' );
} else {
@@ -218,4 +221,8 @@ class LinkSearchPage extends QueryPage {
function getOrderFields() {
return array();
}
+
+ protected function getGroupName() {
+ return 'redirects';
+ }
}
diff --git a/includes/specials/SpecialListfiles.php b/includes/specials/SpecialListfiles.php
index cc055221..c864ae2a 100644
--- a/includes/specials/SpecialListfiles.php
+++ b/includes/specials/SpecialListfiles.php
@@ -23,11 +23,11 @@
class SpecialListFiles extends IncludableSpecialPage {
- public function __construct(){
+ public function __construct() {
parent::__construct( 'Listfiles' );
}
- public function execute( $par ){
+ public function execute( $par ) {
$this->setHeaders();
$this->outputHeader();
@@ -51,6 +51,10 @@ class SpecialListFiles extends IncludableSpecialPage {
}
$this->getOutput()->addHTML( $html );
}
+
+ protected function getGroupName() {
+ return 'media';
+ }
}
/**
@@ -137,7 +141,7 @@ class ImageListPager extends TablePager {
$tables = array( 'image' );
$fields = array_keys( $this->getFieldNames() );
$fields[] = 'img_user';
- $fields[array_search('thumb', $fields)] = 'img_name AS thumb';
+ $fields[array_search( 'thumb', $fields )] = 'img_name AS thumb';
$options = $join_conds = array();
# Depends on $wgMiserMode
@@ -223,7 +227,7 @@ class ImageListPager extends TablePager {
case 'img_size':
return htmlspecialchars( $this->getLanguage()->formatSize( $value ) );
case 'img_description':
- return Linker::commentBlock( $value );
+ return Linker::formatComment( $value );
case 'count':
return intval( $value ) + 1;
}
diff --git a/includes/specials/SpecialListgrouprights.php b/includes/specials/SpecialListgrouprights.php
index 1f95c225..7cccf887 100644
--- a/includes/specials/SpecialListgrouprights.php
+++ b/includes/specials/SpecialListgrouprights.php
@@ -139,15 +139,15 @@ class SpecialListGroupRights extends SpecialPage {
/**
* Create a user-readable list of permissions from the given array.
*
- * @param $permissions Array of permission => bool (from $wgGroupPermissions items)
- * @param $revoke Array of permission => bool (from $wgRevokePermissions items)
- * @param $add Array of groups this group is allowed to add or true
- * @param $remove Array of groups this group is allowed to remove or true
- * @param $addSelf Array of groups this group is allowed to add to self or true
- * @param $removeSelf Array of group this group is allowed to remove from self or true
+ * @param array $permissions of permission => bool (from $wgGroupPermissions items)
+ * @param array $revoke of permission => bool (from $wgRevokePermissions items)
+ * @param array $add of groups this group is allowed to add or true
+ * @param array $remove of groups this group is allowed to remove or true
+ * @param array $addSelf of groups this group is allowed to add to self or true
+ * @param array $removeSelf of group this group is allowed to remove from self or true
* @return string List of all granted permissions, separated by comma separator
*/
- private function formatPermissions( $permissions, $revoke, $add, $remove, $addSelf, $removeSelf ) {
+ private function formatPermissions( $permissions, $revoke, $add, $remove, $addSelf, $removeSelf ) {
$r = array();
foreach( $permissions as $permission => $granted ) {
//show as granted only if it isn't revoked to prevent duplicate display of permissions
@@ -170,7 +170,7 @@ class SpecialListGroupRights extends SpecialPage {
}
sort( $r );
$lang = $this->getLanguage();
- if( $add === true ){
+ if( $add === true ) {
$r[] = $this->msg( 'listgrouprights-addgroup-all' )->escaped();
} elseif( is_array( $add ) && count( $add ) ) {
$add = array_values( array_unique( $add ) );
@@ -179,7 +179,7 @@ class SpecialListGroupRights extends SpecialPage {
count( $add )
)->parse();
}
- if( $remove === true ){
+ if( $remove === true ) {
$r[] = $this->msg( 'listgrouprights-removegroup-all' )->escaped();
} elseif( is_array( $remove ) && count( $remove ) ) {
$remove = array_values( array_unique( $remove ) );
@@ -188,7 +188,7 @@ class SpecialListGroupRights extends SpecialPage {
count( $remove )
)->parse();
}
- if( $addSelf === true ){
+ if( $addSelf === true ) {
$r[] = $this->msg( 'listgrouprights-addgroup-self-all' )->escaped();
} elseif( is_array( $addSelf ) && count( $addSelf ) ) {
$addSelf = array_values( array_unique( $addSelf ) );
@@ -197,7 +197,7 @@ class SpecialListGroupRights extends SpecialPage {
count( $addSelf )
)->parse();
}
- if( $removeSelf === true ){
+ if( $removeSelf === true ) {
$r[] = $this->msg( 'listgrouprights-removegroup-self-all' )->parse();
} elseif( is_array( $removeSelf ) && count( $removeSelf ) ) {
$removeSelf = array_values( array_unique( $removeSelf ) );
@@ -212,4 +212,8 @@ class SpecialListGroupRights extends SpecialPage {
return '<ul><li>' . implode( "</li>\n<li>", $r ) . '</li></ul>';
}
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialListredirects.php b/includes/specials/SpecialListredirects.php
index fe338a08..0283767a 100644
--- a/includes/specials/SpecialListredirects.php
+++ b/includes/specials/SpecialListredirects.php
@@ -34,9 +34,17 @@ class ListredirectsPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
- function sortDescending() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function sortDescending() {
+ return false;
+ }
function getQueryInfo() {
return array(
@@ -77,7 +85,7 @@ class ListredirectsPage extends QueryPage {
$batch->execute();
// Back to start for display
- if ( $db->numRows( $res ) > 0 ) {
+ if ( $res->numRows() > 0 ) {
// If there are no rows we get an error seeking.
$db->dataSeek( $res, 0 );
}
@@ -118,4 +126,8 @@ class ListredirectsPage extends QueryPage {
return "<del>$rd_link</del>";
}
}
+
+ protected function getGroupName() {
+ return 'pages';
+ }
}
diff --git a/includes/specials/SpecialListusers.php b/includes/specials/SpecialListusers.php
index 1089fbbe..d253a4d3 100644
--- a/includes/specials/SpecialListusers.php
+++ b/includes/specials/SpecialListusers.php
@@ -36,7 +36,9 @@ class UsersPager extends AlphabeticPager {
/**
* @param $context IContextSource
- * @param $par null|array
+ * @param array $par (Default null)
+ * @param $including boolean Whether this page is being transcluded in
+ * another page
*/
function __construct( IContextSource $context = null, $par = null, $including = null ) {
if ( $context ) {
@@ -89,7 +91,7 @@ class UsersPager extends AlphabeticPager {
$conds = array();
// Don't show hidden names
if( !$this->getUser()->isAllowed( 'hideuser' ) ) {
- $conds[] = 'ipb_deleted IS NULL';
+ $conds[] = 'ipb_deleted IS NULL OR ipb_deleted = 0';
}
$options = array();
@@ -114,7 +116,7 @@ class UsersPager extends AlphabeticPager {
$options['GROUP BY'] = $this->creationSort ? 'user_id' : 'user_name';
$query = array(
- 'tables' => array( 'user', 'user_groups', 'ipblocks'),
+ 'tables' => array( 'user', 'user_groups', 'ipblocks' ),
'fields' => array(
'user_name' => $this->creationSort ? 'MAX(user_name)' : 'user_name',
'user_id' => $this->creationSort ? 'user_id' : 'MAX(user_id)',
@@ -129,7 +131,6 @@ class UsersPager extends AlphabeticPager {
'user_groups' => array( 'LEFT JOIN', 'user_id=ug_user' ),
'ipblocks' => array( 'LEFT JOIN', array(
'user_id=ipb_user',
- 'ipb_deleted' => 1,
'ipb_auto' => 0
)),
),
@@ -152,7 +153,7 @@ class UsersPager extends AlphabeticPager {
$userName = $row->user_name;
$ulinks = Linker::userLink( $row->user_id, $userName );
- $ulinks .= Linker::userToolLinks( $row->user_id, $userName );
+ $ulinks .= Linker::userToolLinksRedContribs( $row->user_id, $userName, intval( $row->edits ) );
$lang = $this->getLanguage();
@@ -185,9 +186,10 @@ class UsersPager extends AlphabeticPager {
$created = $this->msg( 'usercreated', $d, $t, $row->user_name )->escaped();
$created = ' ' . $this->msg( 'parentheses' )->rawParams( $created )->escaped();
}
+ $blocked = !is_null( $row->ipb_deleted ) ? ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() : '';
wfRunHooks( 'SpecialListusersFormatRow', array( &$item, $row ) );
- return Html::rawElement( 'li', array(), "{$item}{$edits}{$created}" );
+ return Html::rawElement( 'li', array(), "{$item}{$edits}{$created}{$blocked}" );
}
function doBatchLookups() {
@@ -204,23 +206,32 @@ class UsersPager extends AlphabeticPager {
/**
* @return string
*/
- function getPageHeader( ) {
+ function getPageHeader() {
global $wgScript;
list( $self ) = explode( '/', $this->getTitle()->getPrefixedDBkey() );
# Form tag
- $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
+ $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
Xml::fieldset( $this->msg( 'listusers' )->text() ) .
Html::hidden( 'title', $self );
# Username field
$out .= Xml::label( $this->msg( 'listusersfrom' )->text(), 'offset' ) . ' ' .
- Xml::input( 'username', 20, $this->requestedUser, array( 'id' => 'offset' ) ) . ' ';
+ Html::input(
+ 'username',
+ $this->requestedUser,
+ 'text',
+ array(
+ 'id' => 'offset',
+ 'size' => 20,
+ 'autofocus' => $this->requestedUser === ''
+ )
+ ) . ' ';
# Group drop-down list
$out .= Xml::label( $this->msg( 'group' )->text(), 'group' ) . ' ' .
- Xml::openElement('select', array( 'name' => 'group', 'id' => 'group' ) ) .
+ Xml::openElement( 'select', array( 'name' => 'group', 'id' => 'group' ) ) .
Xml::option( $this->msg( 'group-all' )->text(), '' );
foreach( $this->getAllGroups() as $group => $groupText )
$out .= Xml::option( $groupText, $group, $group == $this->requestedGroup );
@@ -286,8 +297,8 @@ class UsersPager extends AlphabeticPager {
/**
* Format a link to a group description page
*
- * @param $group String: group name
- * @param $username String Username
+ * @param string $group group name
+ * @param string $username Username
* @return string
*/
protected static function buildGroupLink( $group, $username ) {
@@ -298,20 +309,19 @@ class UsersPager extends AlphabeticPager {
/**
* @ingroup SpecialPage
*/
-class SpecialListUsers extends SpecialPage {
+class SpecialListUsers extends IncludableSpecialPage {
/**
* Constructor
*/
public function __construct() {
parent::__construct( 'Listusers' );
- $this->mIncludable = true;
}
/**
* Show the special page
*
- * @param $par string (optional) A group to list users from
+ * @param string $par (optional) A group to list users from
*/
public function execute( $par ) {
$this->setHeaders();
@@ -337,4 +347,8 @@ class SpecialListUsers extends SpecialPage {
$this->getOutput()->addHTML( $s );
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialLockdb.php b/includes/specials/SpecialLockdb.php
index d71ac6e1..95ef9510 100644
--- a/includes/specials/SpecialLockdb.php
+++ b/includes/specials/SpecialLockdb.php
@@ -102,4 +102,8 @@ class SpecialLockdb extends FormSpecialPage {
$out->addSubtitle( $this->msg( 'lockdbsuccesssub' ) );
$out->addWikiMsg( 'lockdbsuccesstext' );
}
+
+ protected function getGroupName() {
+ return 'wiki';
+ }
}
diff --git a/includes/specials/SpecialLog.php b/includes/specials/SpecialLog.php
index 7800e566..4fc0f6e8 100644
--- a/includes/specials/SpecialLog.php
+++ b/includes/specials/SpecialLog.php
@@ -182,7 +182,6 @@ class SpecialLog extends SpecialPage {
return $s;
}
-
/**
* Set page title and show header for this log type
* @param $type string
@@ -194,4 +193,7 @@ class SpecialLog extends SpecialPage {
$this->getOutput()->addHTML( $page->getDescription()->parseAsBlock() );
}
+ protected function getGroupName() {
+ return 'changes';
+ }
}
diff --git a/includes/specials/SpecialLonelypages.php b/includes/specials/SpecialLonelypages.php
index 763bbdb1..8c6a88ac 100644
--- a/includes/specials/SpecialLonelypages.php
+++ b/includes/specials/SpecialLonelypages.php
@@ -44,7 +44,10 @@ class LonelyPagesPage extends PageQueryPage {
function isExpensive() {
return true;
}
- function isSyndicated() { return false; }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -78,4 +81,8 @@ class LonelyPagesPage extends PageQueryPage {
return array( 'page_title' );
}
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialLongpages.php b/includes/specials/SpecialLongpages.php
index dd60e37d..c045f9e9 100644
--- a/includes/specials/SpecialLongpages.php
+++ b/includes/specials/SpecialLongpages.php
@@ -34,4 +34,8 @@ class LongPagesPage extends ShortPagesPage {
function sortDescending() {
return true;
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialMIMEsearch.php b/includes/specials/SpecialMIMEsearch.php
index 104c653f..c5a109d4 100644
--- a/includes/specials/SpecialMIMEsearch.php
+++ b/includes/specials/SpecialMIMEsearch.php
@@ -34,9 +34,17 @@ class MIMEsearchPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
- function isCacheable() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function isCacheable() {
+ return false;
+ }
function linkParameters() {
return array( 'mime' => "{$this->major}/{$this->minor}" );
@@ -84,7 +92,6 @@ class MIMEsearchPage extends QueryPage {
parent::execute( $par );
}
-
function formatResult( $skin, $result ) {
global $wgContLang;
@@ -126,4 +133,8 @@ class MIMEsearchPage extends QueryPage {
);
return in_array( $type, $types );
}
+
+ protected function getGroupName() {
+ return 'media';
+ }
}
diff --git a/includes/specials/SpecialMergeHistory.php b/includes/specials/SpecialMergeHistory.php
index 1f057499..1476e156 100644
--- a/includes/specials/SpecialMergeHistory.php
+++ b/includes/specials/SpecialMergeHistory.php
@@ -141,7 +141,7 @@ class SpecialMergeHistory extends SpecialPage {
'<fieldset>' .
Xml::element( 'legend', array(),
$this->msg( 'mergehistory-box' )->text() ) .
- Html::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ) .
+ Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) .
Html::hidden( 'submitted', '1' ) .
Html::hidden( 'mergepoint', $this->mTimestamp ) .
Xml::openElement( 'table' ) .
@@ -373,26 +373,33 @@ class SpecialMergeHistory extends SpecialPage {
$destTitle->getPrefixedText()
)->inContentLanguage()->text();
}
- $mwRedir = MagicWord::get( 'redirect' );
- $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $destTitle->getPrefixedText() . "]]\n";
- $redirectPage = WikiPage::factory( $targetTitle );
- $redirectRevision = new Revision( array(
- 'page' => $this->mTargetID,
- 'comment' => $comment,
- 'text' => $redirectText ) );
- $redirectRevision->insertOn( $dbw );
- $redirectPage->updateRevisionOn( $dbw, $redirectRevision );
-
- # Now, we record the link from the redirect to the new title.
- # It should have no other outgoing links...
- $dbw->delete( 'pagelinks', array( 'pl_from' => $this->mDestID ), __METHOD__ );
- $dbw->insert( 'pagelinks',
- array(
- 'pl_from' => $this->mDestID,
- 'pl_namespace' => $destTitle->getNamespace(),
- 'pl_title' => $destTitle->getDBkey() ),
- __METHOD__
- );
+
+ $contentHandler = ContentHandler::getForTitle( $targetTitle );
+ $redirectContent = $contentHandler->makeRedirectContent( $destTitle );
+
+ if ( $redirectContent ) {
+ $redirectPage = WikiPage::factory( $targetTitle );
+ $redirectRevision = new Revision( array(
+ 'title' => $targetTitle,
+ 'page' => $this->mTargetID,
+ 'comment' => $comment,
+ 'content' => $redirectContent ) );
+ $redirectRevision->insertOn( $dbw );
+ $redirectPage->updateRevisionOn( $dbw, $redirectRevision );
+
+ # Now, we record the link from the redirect to the new title.
+ # It should have no other outgoing links...
+ $dbw->delete( 'pagelinks', array( 'pl_from' => $this->mDestID ), __METHOD__ );
+ $dbw->insert( 'pagelinks',
+ array(
+ 'pl_from' => $this->mDestID,
+ 'pl_namespace' => $destTitle->getNamespace(),
+ 'pl_title' => $destTitle->getDBkey() ),
+ __METHOD__
+ );
+ } else {
+ // would be nice to show a warning if we couldn't create a redirect
+ }
} else {
$targetTitle->invalidateCache(); // update histories
}
@@ -416,6 +423,10 @@ class SpecialMergeHistory extends SpecialPage {
return true;
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
class MergeHistoryPager extends ReverseChronologicalPager {
diff --git a/includes/specials/SpecialMostcategories.php b/includes/specials/SpecialMostcategories.php
index 3f0bafa3..11f26bd7 100644
--- a/includes/specials/SpecialMostcategories.php
+++ b/includes/specials/SpecialMostcategories.php
@@ -35,8 +35,13 @@ class MostcategoriesPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -94,4 +99,8 @@ class MostcategoriesPage extends QueryPage {
return $this->getLanguage()->specialList( $link, $count );
}
+
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMostimages.php b/includes/specials/SpecialMostimages.php
index 3d797908..78b2d911 100644
--- a/includes/specials/SpecialMostimages.php
+++ b/includes/specials/SpecialMostimages.php
@@ -35,8 +35,13 @@ class MostimagesPage extends ImageQueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -53,4 +58,7 @@ class MostimagesPage extends ImageQueryPage {
return $this->msg( 'nimagelinks' )->numParams( $row->value )->escaped() . '<br />';
}
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMostinterwikis.php b/includes/specials/SpecialMostinterwikis.php
index 894d697b..574a9afb 100644
--- a/includes/specials/SpecialMostinterwikis.php
+++ b/includes/specials/SpecialMostinterwikis.php
@@ -35,8 +35,13 @@ class MostinterwikisPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -109,4 +114,8 @@ class MostinterwikisPage extends QueryPage {
return $this->getLanguage()->specialList( $link, $count );
}
+
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMostlinked.php b/includes/specials/SpecialMostlinked.php
index 89c43509..4b6e5670 100644
--- a/includes/specials/SpecialMostlinked.php
+++ b/includes/specials/SpecialMostlinked.php
@@ -36,8 +36,13 @@ class MostlinkedPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -76,7 +81,7 @@ class MostlinkedPage extends QueryPage {
* Make a link to "what links here" for the specified title
*
* @param $title Title being queried
- * @param $caption String: text to display on the link
+ * @param string $caption text to display on the link
* @return String
*/
function makeWlhLink( $title, $caption ) {
@@ -102,4 +107,8 @@ class MostlinkedPage extends QueryPage {
$this->msg( 'nlinks' )->numParams( $result->value )->escaped() );
return $this->getLanguage()->specialList( $link, $wlh );
}
+
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMostlinkedcategories.php b/includes/specials/SpecialMostlinkedcategories.php
index dadef8bf..a1bce45d 100644
--- a/includes/specials/SpecialMostlinkedcategories.php
+++ b/includes/specials/SpecialMostlinkedcategories.php
@@ -35,7 +35,9 @@ class MostlinkedCategoriesPage extends QueryPage {
parent::__construct( $name );
}
- function isSyndicated() { return false; }
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -46,7 +48,9 @@ class MostlinkedCategoriesPage extends QueryPage {
);
}
- function sortDescending() { return true; }
+ function sortDescending() {
+ return true;
+ }
/**
* Fetch user page links and cache their existence
@@ -90,4 +94,8 @@ class MostlinkedCategoriesPage extends QueryPage {
$nlinks = $this->msg( 'nmembers' )->numParams( $result->value )->escaped();
return $this->getLanguage()->specialList( $plink, $nlinks );
}
+
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMostlinkedtemplates.php b/includes/specials/SpecialMostlinkedtemplates.php
index 22932e5c..506e6b22 100644
--- a/includes/specials/SpecialMostlinkedtemplates.php
+++ b/includes/specials/SpecialMostlinkedtemplates.php
@@ -124,5 +124,8 @@ class MostlinkedTemplatesPage extends QueryPage {
$label = $this->msg( 'ntransclusions' )->numParams( $result->value )->escaped();
return Linker::link( $wlh, $label );
}
-}
+ protected function getGroupName() {
+ return 'highuse';
+ }
+}
diff --git a/includes/specials/SpecialMostrevisions.php b/includes/specials/SpecialMostrevisions.php
index b0253316..ad6b788d 100644
--- a/includes/specials/SpecialMostrevisions.php
+++ b/includes/specials/SpecialMostrevisions.php
@@ -31,4 +31,8 @@ class MostrevisionsPage extends FewestrevisionsPage {
function sortDescending() {
return true;
}
+
+ protected function getGroupName() {
+ return 'highuse';
+ }
}
diff --git a/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php
index af3dbf3e..4adb0371 100644
--- a/includes/specials/SpecialMovepage.php
+++ b/includes/specials/SpecialMovepage.php
@@ -71,7 +71,6 @@ class MovePageForm extends UnlistedSpecialPage {
? Title::newFromText( $newTitleText_bc )
: Title::makeTitleSafe( $newTitleTextNs, $newTitleTextMain );
-
$user = $this->getUser();
# Check rights
@@ -104,7 +103,7 @@ class MovePageForm extends UnlistedSpecialPage {
/**
* Show the form
*
- * @param $err Array: error messages. Each item is an error message.
+ * @param array $err error messages. Each item is an error message.
* It may either be a string message name or array message name and
* parameters, like the second argument to OutputPage::wrapWikiMsg().
*/
@@ -152,7 +151,7 @@ class MovePageForm extends UnlistedSpecialPage {
</tr>";
$err = array();
} else {
- if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
+ if ( $this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
$out->wrapWikiMsg( "<div class=\"error mw-moveuserpage-warning\">\n$1\n</div>", 'moveuserpage-warning' );
}
$out->addWikiMsg( $wgFixDoubleRedirects ? 'movepagetext' :
@@ -189,7 +188,7 @@ class MovePageForm extends UnlistedSpecialPage {
array(
'rd_namespace' => $this->oldTitle->getNamespace(),
'rd_title' => $this->oldTitle->getDBkey(),
- ) , __METHOD__ );
+ ), __METHOD__ );
} else {
$hasRedirects = false;
}
@@ -254,12 +253,14 @@ class MovePageForm extends UnlistedSpecialPage {
}
}
+ $handler = ContentHandler::getForTitle( $this->oldTitle );
+
$out->addHTML(
- Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
- Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
- Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
- "<tr>
+ Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
+ Xml::openElement( 'fieldset' ) .
+ Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
+ Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
+ "<tr>
<td class='mw-label'>" .
$this->msg( 'movearticle' )->escaped() .
"</td>
@@ -309,7 +310,7 @@ class MovePageForm extends UnlistedSpecialPage {
);
}
- if ( $user->isAllowed( 'suppressredirect' ) ) {
+ if ( $user->isAllowed( 'suppressredirect' ) && $handler->supportsRedirects() ) {
$out->addHTML( "
<tr>
<td></td>
@@ -342,7 +343,7 @@ class MovePageForm extends UnlistedSpecialPage {
'wpMovesubpages',
# Don't check the box if we only have talk subpages to
# move and we aren't moving the talk page.
- $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk),
+ $this->moveSubpages && ( $this->oldTitle->hasSubpages() || $this->moveTalk ),
array( 'id' => 'wpMovesubpages' )
) . '&#160;' .
Xml::tags( 'label', array( 'for' => 'wpMovesubpages' ),
@@ -357,7 +358,7 @@ class MovePageForm extends UnlistedSpecialPage {
);
}
- $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption( 'watchmoves' )
+ $watchChecked = $user->isLoggedIn() && ( $this->watch || $user->getBoolOption( 'watchmoves' )
|| $user->isWatched( $this->oldTitle ) );
# Don't allow watching if user is not logged in
if( $user->isLoggedIn() ) {
@@ -447,7 +448,11 @@ class MovePageForm extends UnlistedSpecialPage {
}
}
- if ( $user->isAllowed( 'suppressredirect' ) ) {
+ $handler = ContentHandler::getForTitle( $ot );
+
+ if ( !$handler->supportsRedirects() ) {
+ $createRedirect = false;
+ } elseif ( $user->isAllowed( 'suppressredirect' ) ) {
$createRedirect = $this->leaveRedirect;
} else {
$createRedirect = true;
@@ -464,8 +469,6 @@ class MovePageForm extends UnlistedSpecialPage {
DoubleRedirectJob::fixRedirects( 'move', $ot, $nt );
}
- wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
-
$out = $this->getOutput();
$out->setPageTitle( $this->msg( 'pagemovedsub' ) );
@@ -479,11 +482,23 @@ class MovePageForm extends UnlistedSpecialPage {
$oldText = $ot->getPrefixedText();
$newText = $nt->getPrefixedText();
- $msgName = $createRedirect ? 'movepage-moved-redirect' : 'movepage-moved-noredirect';
+ if ( $ot->exists() ) {
+ //NOTE: we assume that if the old title exists, it's because it was re-created as
+ // a redirect to the new title. This is not safe, but what we did before was
+ // even worse: we just determined whether a redirect should have been created,
+ // and reported that it was created if it should have, without any checks.
+ // Also note that isRedirect() is unreliable because of bug 37209.
+ $msgName = 'movepage-moved-redirect';
+ } else {
+ $msgName = 'movepage-moved-noredirect';
+ }
+
$out->addHTML( $this->msg( 'movepage-moved' )->rawParams( $oldLink,
$newLink )->params( $oldText, $newText )->parseAsBlock() );
$out->addWikiMsg( $msgName );
+ wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
+
# Now we move extra pages we've been asked to move: subpages and talk
# pages. First, if the old page or the new page is a talk page, we
# can't move any talk pages: cancel that.
@@ -521,10 +536,10 @@ class MovePageForm extends UnlistedSpecialPage {
);
$conds['page_namespace'] = array();
if( MWNamespace::hasSubpages( $nt->getNamespace() ) ) {
- $conds['page_namespace'] []= $ot->getNamespace();
+ $conds['page_namespace'][] = $ot->getNamespace();
}
if( $this->moveTalk && MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) ) {
- $conds['page_namespace'] []= $ot->getTalkPage()->getNamespace();
+ $conds['page_namespace'][] = $ot->getTalkPage()->getNamespace();
}
} elseif( $this->moveTalk ) {
$conds = array(
@@ -570,7 +585,7 @@ class MovePageForm extends UnlistedSpecialPage {
$newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
if( !$newSubpage ) {
$oldLink = Linker::linkKnown( $oldSubpage );
- $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
+ $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
)->params( Title::makeName( $newNs, $newPageName ) )->escaped();
continue;
}
@@ -578,7 +593,7 @@ class MovePageForm extends UnlistedSpecialPage {
# This was copy-pasted from Renameuser, bleh.
if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) {
$link = Linker::linkKnown( $newSubpage );
- $extraOutput []= $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
+ $extraOutput[] = $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
} else {
$success = $oldSubpage->moveTo( $newSubpage, true, $this->reason, $createRedirect );
if( $success === true ) {
@@ -592,16 +607,16 @@ class MovePageForm extends UnlistedSpecialPage {
array( 'redirect' => 'no' )
);
$newLink = Linker::linkKnown( $newSubpage );
- $extraOutput []= $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
+ $extraOutput[] = $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
++$count;
if( $count >= $wgMaximumMovedPages ) {
- $extraOutput []= $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
+ $extraOutput[] = $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
break;
}
} else {
$oldLink = Linker::linkKnown( $oldSubpage );
$newLink = Linker::link( $newSubpage );
- $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
+ $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
}
}
@@ -660,4 +675,8 @@ class MovePageForm extends UnlistedSpecialPage {
}
$out->addHTML( "</ul>\n" );
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
diff --git a/includes/specials/SpecialNewimages.php b/includes/specials/SpecialNewimages.php
index 350aac63..52cbc3aa 100644
--- a/includes/specials/SpecialNewimages.php
+++ b/includes/specials/SpecialNewimages.php
@@ -22,11 +22,11 @@
*/
class SpecialNewFiles extends IncludableSpecialPage {
- public function __construct(){
+ public function __construct() {
parent::__construct( 'Newimages' );
}
- public function execute( $par ){
+ public function execute( $par ) {
$this->setHeaders();
$this->outputHeader();
@@ -42,8 +42,11 @@ class SpecialNewFiles extends IncludableSpecialPage {
$this->getOutput()->addHTML( $pager->getNavigationBar() );
}
}
-}
+ protected function getGroupName() {
+ return 'changes';
+ }
+}
/**
* @ingroup SpecialPage Pager
@@ -57,7 +60,7 @@ class NewFilesPager extends ReverseChronologicalPager {
function __construct( IContextSource $context, $par = null ) {
$this->like = $context->getRequest()->getText( 'like' );
- $this->showbots = $context->getRequest()->getBool( 'showbots' , 0 );
+ $this->showbots = $context->getRequest()->getBool( 'showbots', 0 );
if ( is_numeric( $par ) ) {
$this->setLimit( $par );
}
@@ -85,10 +88,10 @@ class NewFilesPager extends ReverseChronologicalPager {
}
}
- if( !$wgMiserMode && $this->like !== null ){
+ if( !$wgMiserMode && $this->like !== null ) {
$dbr = wfGetDB( DB_SLAVE );
$likeObj = Title::newFromURL( $this->like );
- if( $likeObj instanceof Title ){
+ if( $likeObj instanceof Title ) {
$like = $dbr->buildLike( $dbr->anyString(), strtolower( $likeObj->getDBkey() ), $dbr->anyString() );
$conds[] = "LOWER(img_name) $like";
}
@@ -104,18 +107,18 @@ class NewFilesPager extends ReverseChronologicalPager {
return $query;
}
- function getIndexField(){
+ function getIndexField() {
return 'img_timestamp';
}
- function getStartBody(){
+ function getStartBody() {
if ( !$this->gallery ) {
$this->gallery = new ImageGallery();
}
return '';
}
- function getEndBody(){
+ function getEndBody() {
return $this->gallery->toHTML();
}
@@ -161,7 +164,7 @@ class NewFilesPager extends ReverseChronologicalPager {
),
);
- if( $wgMiserMode ){
+ if( $wgMiserMode ) {
unset( $fields['like'] );
}
diff --git a/includes/specials/SpecialNewpages.php b/includes/specials/SpecialNewpages.php
index 8e15d554..ebb3021d 100644
--- a/includes/specials/SpecialNewpages.php
+++ b/includes/specials/SpecialNewpages.php
@@ -53,12 +53,13 @@ class SpecialNewpages extends IncludableSpecialPage {
$opts->add( 'hidepatrolled', $this->getUser()->getBoolOption( 'newpageshidepatrolled' ) );
$opts->add( 'hidebots', false );
$opts->add( 'hideredirs', true );
- $opts->add( 'limit', (int)$this->getUser()->getOption( 'rclimit' ) );
+ $opts->add( 'limit', $this->getUser()->getIntOption( 'rclimit' ) );
$opts->add( 'offset', '' );
$opts->add( 'namespace', '0' );
$opts->add( 'username', '' );
$opts->add( 'feed', '' );
$opts->add( 'tagfilter', '' );
+ $opts->add( 'invert', false );
$this->customFilters = array();
wfRunHooks( 'SpecialNewPagesFilters', array( $this, &$this->customFilters ) );
@@ -105,7 +106,7 @@ class SpecialNewpages extends IncludableSpecialPage {
}
// PG offsets not just digits!
if ( preg_match( '/^offset=([^=]+)$/', $bit, $m ) ) {
- $this->opts->setValue( 'offset', intval( $m[1] ) );
+ $this->opts->setValue( 'offset', intval( $m[1] ) );
}
if ( preg_match( '/^username=(.*)$/', $bit, $m ) ) {
$this->opts->setValue( 'username', $m[1] );
@@ -113,7 +114,7 @@ class SpecialNewpages extends IncludableSpecialPage {
if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) {
$ns = $this->getLanguage()->getNsIndex( $m[1] );
if( $ns !== false ) {
- $this->opts->setValue( 'namespace', $ns );
+ $this->opts->setValue( 'namespace', $ns );
}
}
}
@@ -140,12 +141,13 @@ class SpecialNewpages extends IncludableSpecialPage {
$feedType = $this->opts->getValue( 'feed' );
if( $feedType ) {
- return $this->feed( $feedType );
+ $this->feed( $feedType );
+ return;
}
$allValues = $this->opts->getAllValues();
unset( $allValues['feed'] );
- $out->setFeedAppendQuery( wfArrayToCGI( $allValues ) );
+ $out->setFeedAppendQuery( wfArrayToCgi( $allValues ) );
}
$pager = new NewPagesPager( $this, $this->opts );
@@ -164,8 +166,6 @@ class SpecialNewpages extends IncludableSpecialPage {
}
protected function filterLinks() {
- global $wgGroupPermissions;
-
// show/hide links
$showhide = array( $this->msg( 'show' )->escaped(), $this->msg( 'hide' )->escaped() );
@@ -181,8 +181,7 @@ class SpecialNewpages extends IncludableSpecialPage {
}
// Disable some if needed
- # @todo FIXME: Throws E_NOTICEs if not set; and doesn't obey hooks etc.
- if ( $wgGroupPermissions['*']['createpage'] !== true ) {
+ if ( !User::groupHasPermission( '*', 'createpage' ) ) {
unset( $filters['hideliu'] );
}
if ( !$this->getUser()->useNPPatrol() ) {
@@ -213,6 +212,7 @@ class SpecialNewpages extends IncludableSpecialPage {
$namespace = $this->opts->consumeValue( 'namespace' );
$username = $this->opts->consumeValue( 'username' );
$tagFilterVal = $this->opts->consumeValue( 'tagfilter' );
+ $nsinvert = $this->opts->consumeValue( 'invert' );
// Check username input validity
$ut = Title::makeTitleSafe( NS_USER, $username );
@@ -248,6 +248,13 @@ class SpecialNewpages extends IncludableSpecialPage {
'id' => 'namespace',
'class' => 'namespaceselector',
)
+ ) . '&#160;' .
+ Xml::checkLabel(
+ $this->msg( 'invert' )->text(),
+ 'invert',
+ 'nsinvert',
+ $nsinvert,
+ array( 'title' => $this->msg( 'tooltip-invert' )->text() )
) .
'</td>
</tr>' . ( $tagFilter ? (
@@ -298,11 +305,11 @@ class SpecialNewpages extends IncludableSpecialPage {
# Revision deletion works on revisions, so we should cast one
$row = array(
- 'comment' => $result->rc_comment,
- 'deleted' => $result->rc_deleted,
- 'user_text' => $result->rc_user_text,
- 'user' => $result->rc_user,
- );
+ 'comment' => $result->rc_comment,
+ 'deleted' => $result->rc_deleted,
+ 'user_text' => $result->rc_user_text,
+ 'user' => $result->rc_user,
+ );
$rev = new Revision( $row );
$rev->setTitle( $title );
@@ -328,12 +335,13 @@ class SpecialNewpages extends IncludableSpecialPage {
$query['rcid'] = $result->rc_id;
}
- $plink = Linker::linkKnown(
+ // Linker::linkKnown() uses 'known' and 'noclasses' options. This breaks the colouration for stubs.
+ $plink = Linker::link(
$title,
null,
array( 'class' => 'mw-newpages-pagename' ),
$query,
- array( 'known' ) // Set explicitly to avoid the default of 'known','noclasses'. This breaks the colouration for stubs
+ array( 'known' )
);
$histLink = Linker::linkKnown(
$title,
@@ -459,14 +467,19 @@ class SpecialNewpages extends IncludableSpecialPage {
protected function feedItemDesc( $row ) {
$revision = Revision::newFromId( $row->rev_id );
if( $revision ) {
+ //XXX: include content model/type in feed item?
return '<p>' . htmlspecialchars( $revision->getUserText() ) .
$this->msg( 'colon-separator' )->inContentLanguage()->escaped() .
htmlspecialchars( FeedItem::stripComment( $revision->getComment() ) ) .
"</p>\n<hr />\n<div>" .
- nl2br( htmlspecialchars( $revision->getText() ) ) . "</div>";
+ nl2br( htmlspecialchars( $revision->getContent()->serialize() ) ) . "</div>";
}
return '';
}
+
+ protected function getGroupName() {
+ return 'changes';
+ }
}
/**
@@ -488,7 +501,7 @@ class NewPagesPager extends ReverseChronologicalPager {
}
function getQueryInfo() {
- global $wgEnableNewpagesUserFilter, $wgGroupPermissions;
+ global $wgEnableNewpagesUserFilter;
$conds = array();
$conds['rc_new'] = 1;
@@ -499,7 +512,11 @@ class NewPagesPager extends ReverseChronologicalPager {
$user = Title::makeTitleSafe( NS_USER, $username );
if( $namespace !== false ) {
- $conds['rc_namespace'] = $namespace;
+ if ( $this->opts->getValue( 'invert' ) ) {
+ $conds[] = 'rc_namespace != ' . $this->mDb->addQuotes( $namespace );
+ } else {
+ $conds['rc_namespace'] = $namespace;
+ }
$rcIndexes = array( 'new_name_timestamp' );
} else {
$rcIndexes = array( 'rc_timestamp' );
@@ -510,7 +527,7 @@ class NewPagesPager extends ReverseChronologicalPager {
$conds['rc_user_text'] = $user->getText();
$rcIndexes = 'rc_user_text';
# If anons cannot make new pages, don't "exclude logged in users"!
- } elseif( $wgGroupPermissions['*']['createpage'] && $this->opts->getValue( 'hideliu' ) ) {
+ } elseif( User::groupHasPermission( '*', 'createpage' ) && $this->opts->getValue( 'hideliu' ) ) {
$conds['rc_user'] = 0;
}
# If this user cannot see patrolled edits or they are off, don't do dumb queries!
diff --git a/includes/specials/SpecialPagesWithProp.php b/includes/specials/SpecialPagesWithProp.php
new file mode 100644
index 00000000..8f8c981e
--- /dev/null
+++ b/includes/specials/SpecialPagesWithProp.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Implements Special:PagesWithProp
+ *
+ * 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
+ *
+ * @since 1.21
+ * @file
+ * @ingroup SpecialPage
+ * @author Brad Jorsch
+ */
+
+
+/**
+ * Special:PagesWithProp to search the page_props table
+ * @ingroup SpecialPage
+ * @since 1.21
+ */
+class SpecialPagesWithProp extends QueryPage {
+ private $propName = null;
+
+ function __construct( $name = 'PagesWithProp' ) {
+ parent::__construct( $name );
+ }
+
+ function isCacheable() {
+ return false;
+ }
+
+ function execute( $par ) {
+ $this->setHeaders();
+ $this->outputHeader();
+
+ $request = $this->getRequest();
+ $propname = $request->getVal( 'propname', $par );
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $res = $dbr->select(
+ 'page_props',
+ 'pp_propname',
+ '',
+ __METHOD__,
+ array( 'DISTINCT', 'ORDER BY' => 'pp_propname' )
+ );
+ foreach ( $res as $row ) {
+ $propnames[$row->pp_propname] = $row->pp_propname;
+ }
+
+ $form = new HTMLForm( array(
+ 'propname' => array(
+ 'type' => 'selectorother',
+ 'name' => 'propname',
+ 'options' => $propnames,
+ 'default' => $propname,
+ 'label-message' => 'pageswithprop-prop',
+ 'required' => true,
+ ),
+ ), $this->getContext() );
+ $form->setMethod( 'get' );
+ $form->setAction( $this->getTitle()->getFullUrl() );
+ $form->setSubmitCallback( array( $this, 'onSubmit' ) );
+ $form->setWrapperLegend( $this->msg( 'pageswithprop-legend' ) );
+ $form->addHeaderText( $this->msg( 'pageswithprop-text' )->parseAsBlock() );
+ $form->setSubmitTextMsg( 'pageswithprop-submit' );
+
+ $form->prepareForm();
+ $form->displayForm( false );
+ if ( $propname !== '' && $propname !== null ) {
+ $form->trySubmit();
+ }
+ }
+
+ public function onSubmit( $data, $form ) {
+ $this->propName = $data['propname'];
+ parent::execute( $data['propname'] );
+ }
+
+ /**
+ * Disable RSS/Atom feeds
+ * @return bool
+ */
+ function isSyndicated() {
+ return false;
+ }
+
+ function getQueryInfo() {
+ return array(
+ 'tables' => array( 'page_props', 'page' ),
+ 'fields' => array(
+ 'page_id' => 'pp_page',
+ 'page_namespace',
+ 'page_title',
+ 'page_len',
+ 'page_is_redirect',
+ 'page_latest',
+ 'pp_value',
+ ),
+ 'conds' => array(
+ 'page_id = pp_page',
+ 'pp_propname' => $this->propName,
+ ),
+ 'options' => array()
+ );
+ }
+
+ function getOrderFields() {
+ return array( 'page_id' );
+ }
+
+ function formatResult( $skin, $result ) {
+ $title = Title::newFromRow( $result );
+ $ret = Linker::link( $title, null, array(), array(), array( 'known' ) );
+ if ( $result->pp_value !== '' ) {
+ $value = $this->msg( 'parentheses' )
+ ->rawParams( Xml::span( $result->pp_value, 'prop-value' ) )
+ ->escaped();
+ $ret .= " $value";
+ }
+ return $ret;
+ }
+
+ protected function getGroupName() {
+ return 'pages';
+ }
+}
diff --git a/includes/specials/SpecialPasswordReset.php b/includes/specials/SpecialPasswordReset.php
index efb57657..90b0ac80 100644
--- a/includes/specials/SpecialPasswordReset.php
+++ b/includes/specials/SpecialPasswordReset.php
@@ -86,7 +86,7 @@ class SpecialPasswordReset extends FormSpecialPage {
);
}
- if( $this->getUser()->isAllowed( 'passwordreset' ) ){
+ if( $this->getUser()->isAllowed( 'passwordreset' ) ) {
$a['Capture'] = array(
'type' => 'check',
'label-message' => 'passwordreset-capture',
@@ -121,6 +121,8 @@ class SpecialPasswordReset extends FormSpecialPage {
* userCanExecute(), and if the data array contains 'Username', etc, then Username
* resets are allowed.
* @param $data array
+ * @throws MWException
+ * @throws ThrottledError|PermissionsError
* @return Bool|Array
*/
public function onSubmit( array $data ) {
@@ -134,7 +136,7 @@ class SpecialPasswordReset extends FormSpecialPage {
}
}
- if( isset( $data['Capture'] ) && !$this->getUser()->isAllowed( 'passwordreset' ) ){
+ if( isset( $data['Capture'] ) && !$this->getUser()->isAllowed( 'passwordreset' ) ) {
// The user knows they don't have the passwordreset permission, but they tried to spoof the form. That's naughty
throw new PermissionsError( 'passwordreset' );
}
@@ -160,7 +162,7 @@ class SpecialPasswordReset extends FormSpecialPage {
);
if ( $res ) {
$users = array();
- foreach( $res as $row ){
+ foreach( $res as $row ) {
$users[] = User::newFromRow( $row );
}
} else {
@@ -178,8 +180,8 @@ class SpecialPasswordReset extends FormSpecialPage {
return array( $error );
}
- if( count( $users ) == 0 ){
- if( $method == 'email' ){
+ if( count( $users ) == 0 ) {
+ if( $method == 'email' ) {
// Don't reveal whether or not an email address is in use
return true;
} else {
@@ -247,13 +249,13 @@ class SpecialPasswordReset extends FormSpecialPage {
$username,
$passwordBlock,
count( $passwords ),
- Title::newMainPage()->getCanonicalUrl(),
+ '<' . Title::newMainPage()->getCanonicalUrl() . '>',
round( $wgNewPasswordExpiry / 86400 )
);
$title = $this->msg( 'passwordreset-emailtitle' );
- $this->result = $firstUser->sendMail( $title->escaped(), $this->email->escaped() );
+ $this->result = $firstUser->sendMail( $title->escaped(), $this->email->text() );
// Blank the email if the user is not supposed to see it
if( !isset( $data['Capture'] ) || !$data['Capture'] ) {
@@ -262,7 +264,7 @@ class SpecialPasswordReset extends FormSpecialPage {
if ( $this->result->isGood() ) {
return true;
- } elseif( isset( $data['Capture'] ) && $data['Capture'] ){
+ } elseif( isset( $data['Capture'] ) && $data['Capture'] ) {
// The email didn't send, but maybe they knew that and that's why they captured it
return true;
} else {
@@ -273,10 +275,10 @@ class SpecialPasswordReset extends FormSpecialPage {
}
public function onSuccess() {
- if( $this->getUser()->isAllowed( 'passwordreset' ) && $this->email != null ){
+ if( $this->getUser()->isAllowed( 'passwordreset' ) && $this->email != null ) {
// @todo: Logging
- if( $this->result->isGood() ){
+ if( $this->result->isGood() ) {
$this->getOutput()->addWikiMsg( 'passwordreset-emailsent-capture' );
} else {
$this->getOutput()->addWikiMsg( 'passwordreset-emailerror-capture', $this->result->getMessage() );
@@ -324,4 +326,8 @@ class SpecialPasswordReset extends FormSpecialPage {
return false;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialPopularpages.php b/includes/specials/SpecialPopularpages.php
index 448d1799..7ce8c13f 100644
--- a/includes/specials/SpecialPopularpages.php
+++ b/includes/specials/SpecialPopularpages.php
@@ -37,14 +37,16 @@ class PopularPagesPage extends QueryPage {
return true;
}
- function isSyndicated() { return false; }
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
'tables' => array( 'page' ),
'fields' => array( 'namespace' => 'page_namespace',
'title' => 'page_title',
- 'value' => 'page_counter'),
+ 'value' => 'page_counter' ),
'conds' => array( 'page_is_redirect' => 0,
'page_namespace' => MWNamespace::getContentNamespaces() ) );
}
@@ -70,4 +72,8 @@ class PopularPagesPage extends QueryPage {
$nv = $this->msg( 'nviews' )->numParams( $result->value )->escaped();
return $this->getLanguage()->specialList( $link, $nv );
}
+
+ protected function getGroupName() {
+ return 'wiki';
+ }
}
diff --git a/includes/specials/SpecialPreferences.php b/includes/specials/SpecialPreferences.php
index c6b2bb6b..a50e7c18 100644
--- a/includes/specials/SpecialPreferences.php
+++ b/includes/specials/SpecialPreferences.php
@@ -78,7 +78,7 @@ class SpecialPreferences extends SpecialPage {
public function submitReset( $formData ) {
$user = $this->getUser();
- $user->resetOptions();
+ $user->resetOptions( 'all' );
$user->saveSettings();
$url = $this->getTitle()->getFullURL( 'success' );
@@ -87,4 +87,8 @@ class SpecialPreferences extends SpecialPage {
return true;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialPrefixindex.php b/includes/specials/SpecialPrefixindex.php
index 7740b320..6affa735 100644
--- a/includes/specials/SpecialPrefixindex.php
+++ b/includes/specials/SpecialPrefixindex.php
@@ -29,13 +29,13 @@
class SpecialPrefixindex extends SpecialAllpages {
// Inherit $maxPerPage
- function __construct(){
+ function __construct() {
parent::__construct( 'Prefixindex' );
}
/**
* Entry point : initialise variables and call subfunctions.
- * @param $par String: becomes "FOO" when called like Special:Prefixindex/FOO (default null)
+ * @param string $par becomes "FOO" when called like Special:Prefixindex/FOO (default null)
*/
function execute( $par ) {
global $wgContLang;
@@ -83,14 +83,14 @@ class SpecialPrefixindex extends SpecialAllpages {
/**
* HTML for the top form
* @param $namespace Integer: a namespace constant (default NS_MAIN).
- * @param $from String: dbKey we are starting listing at.
- * @param $hideredirects Bool: hide redirects (default FALSE)
+ * @param string $from dbKey we are starting listing at.
+ * @param bool $hideredirects hide redirects (default FALSE)
* @return string
*/
function namespacePrefixForm( $namespace = NS_MAIN, $from = '', $hideredirects = false ) {
global $wgScript;
- $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
+ $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
$out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
$out .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() );
$out .= Xml::openElement( 'fieldset' );
@@ -101,7 +101,7 @@ class SpecialPrefixindex extends SpecialAllpages {
Xml::label( $this->msg( 'allpagesprefix' )->text(), 'nsfrom' ) .
"</td>
<td class='mw-input'>" .
- Xml::input( 'prefix', 30, str_replace('_',' ',$from), array( 'id' => 'nsfrom' ) ) .
+ Xml::input( 'prefix', 30, str_replace( '_', ' ', $from ), array( 'id' => 'nsfrom' ) ) .
"</td>
</tr>
<tr>
@@ -135,8 +135,8 @@ class SpecialPrefixindex extends SpecialAllpages {
/**
* @param $namespace Integer, default NS_MAIN
* @param $prefix String
- * @param $from String: list all pages from this name (default FALSE)
- * @param $hideredirects Bool: hide redirects (default FALSE)
+ * @param string $from list all pages from this name (default FALSE)
+ * @param bool $hideredirects hide redirects (default FALSE)
*/
function showPrefixChunk( $namespace = NS_MAIN, $prefix, $from = null, $hideredirects = false ) {
global $wgContLang;
@@ -145,8 +145,8 @@ class SpecialPrefixindex extends SpecialAllpages {
$from = $prefix;
}
- $fromList = $this->getNamespaceKeyAndText($namespace, $from);
- $prefixList = $this->getNamespaceKeyAndText($namespace, $prefix);
+ $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
+ $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
$namespaces = $wgContLang->getNamespaces();
if ( !$prefixList || !$fromList ) {
@@ -227,7 +227,7 @@ class SpecialPrefixindex extends SpecialAllpages {
} else {
$nsForm = $this->namespacePrefixForm( $namespace, $prefix, $hideredirects );
$self = $this->getTitle();
- $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) ) .
+ $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) ) .
'<tr>
<td>' .
$nsForm .
@@ -241,14 +241,14 @@ class SpecialPrefixindex extends SpecialAllpages {
'hideredirects' => $hideredirects,
);
- if( $namespace || ($prefix == '')) {
+ if( $namespace || $prefix == '' ) {
// Keep the namespace even if it's 0 for empty prefixes.
// This tells us we're not just a holdover from old links.
$query['namespace'] = $namespace;
}
$nextLink = Linker::linkKnown(
$self,
- $this->msg( 'nextpage', str_replace( '_',' ', $s->page_title ) )->escaped(),
+ $this->msg( 'nextpage', str_replace( '_', ' ', $s->page_title ) )->escaped(),
array(),
$query
);
@@ -263,4 +263,8 @@ class SpecialPrefixindex extends SpecialAllpages {
$this->getOutput()->addHTML( $out2 . $out . $footer );
}
+
+ protected function getGroupName() {
+ return 'pages';
+ }
}
diff --git a/includes/specials/SpecialProtectedpages.php b/includes/specials/SpecialProtectedpages.php
index 74ed5378..cdf053ec 100644
--- a/includes/specials/SpecialProtectedpages.php
+++ b/includes/specials/SpecialProtectedpages.php
@@ -29,7 +29,7 @@
class SpecialProtectedpages extends SpecialPage {
protected $IdLevel = 'level';
- protected $IdType = 'type';
+ protected $IdType = 'type';
public function __construct() {
parent::__construct( 'Protectedpages' );
@@ -51,7 +51,7 @@ class SpecialProtectedpages extends SpecialPage {
$size = $request->getIntOrNull( 'size' );
$NS = $request->getIntOrNull( 'namespace' );
$indefOnly = $request->getBool( 'indefonly' ) ? 1 : 0;
- $cascadeOnly = $request->getBool('cascadeonly') ? 1 : 0;
+ $cascadeOnly = $request->getBool( 'cascadeonly' ) ? 1 : 0;
$pager = new ProtectedPagesPager( $this, array(), $type, $level, $NS, $sizetype, $size, $indefOnly, $cascadeOnly );
@@ -78,11 +78,17 @@ class SpecialProtectedpages extends SpecialPage {
static $infinity = null;
- if( is_null( $infinity ) ){
+ if( is_null( $infinity ) ) {
$infinity = wfGetDB( DB_SLAVE )->getInfinity();
}
$title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+ if( !$title ) {
+ return Html::rawElement( 'li', array(),
+ Html::element( 'span', array( 'class' => 'mw-invalidtitle' ),
+ Linker::getInvalidTitleDescription( $this->getContext(), $row->page_namespace, $row->page_title ) ) ) . "\n";
+ }
+
$link = Linker::link( $title );
$description_items = array ();
@@ -109,7 +115,7 @@ class SpecialProtectedpages extends SpecialPage {
)->escaped();
}
- if(!is_null($size = $row->page_len)) {
+ if( !is_null( $size = $row->page_len ) ) {
$stxt = $lang->getDirMark() . ' ' . Linker::formatRevisionSize( $size );
}
@@ -146,15 +152,15 @@ class SpecialProtectedpages extends SpecialPage {
/**
* @param $namespace Integer
- * @param $type String: restriction type
- * @param $level String: restriction level
- * @param $sizetype String: "min" or "max"
+ * @param string $type restriction type
+ * @param string $level restriction level
+ * @param string $sizetype "min" or "max"
* @param $size Integer
* @param $indefOnly Boolean: only indefinie protection
* @param $cascadeOnly Boolean: only cascading protection
* @return String: input form
*/
- protected function showOptions( $namespace, $type='edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
+ protected function showOptions( $namespace, $type = 'edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
global $wgScript;
$title = $this->getTitle();
return Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
@@ -272,7 +278,7 @@ class SpecialProtectedpages extends SpecialPage {
// First pass to load the log names
foreach( $wgRestrictionLevels as $type ) {
// Messages used can be 'restriction-level-sysop' and 'restriction-level-autoconfirmed'
- if( $type !='' && $type !='*') {
+ if( $type != '' && $type != '*' ) {
$text = $this->msg( "restriction-level-$type" )->text();
$m[$text] = $type;
}
@@ -290,6 +296,10 @@ class SpecialProtectedpages extends SpecialPage {
array( 'id' => $this->IdLevel, 'name' => $this->IdLevel ),
implode( "\n", $options ) ) . "</span>";
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
/**
@@ -300,7 +310,7 @@ class ProtectedPagesPager extends AlphabeticPager {
public $mForm, $mConds;
private $type, $level, $namespace, $sizetype, $size, $indefonly;
- function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0,
+ function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0,
$indefonly = false, $cascadeonly = false )
{
$this->mForm = $form;
@@ -309,7 +319,7 @@ class ProtectedPagesPager extends AlphabeticPager {
$this->level = $level;
$this->namespace = $namespace;
$this->sizetype = $sizetype;
- $this->size = intval($size);
+ $this->size = intval( $size );
$this->indefonly = (bool)$indefonly;
$this->cascadeonly = (bool)$cascadeonly;
parent::__construct( $form->getContext() );
@@ -336,27 +346,27 @@ class ProtectedPagesPager extends AlphabeticPager {
$conds[] = 'page_id=pr_page';
$conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
- if( $this->sizetype=='min' ) {
+ if( $this->sizetype == 'min' ) {
$conds[] = 'page_len>=' . $this->size;
- } elseif( $this->sizetype=='max' ) {
+ } elseif( $this->sizetype == 'max' ) {
$conds[] = 'page_len<=' . $this->size;
}
if( $this->indefonly ) {
- $db = wfGetDB( DB_SLAVE );
- $conds[] = "pr_expiry = {$db->addQuotes( $db->getInfinity() )} OR pr_expiry IS NULL";
+ $conds[] = "pr_expiry = {$this->mDb->addQuotes( $this->mDb->getInfinity() )} OR pr_expiry IS NULL";
}
if( $this->cascadeonly ) {
- $conds[] = "pr_cascade = '1'";
+ $conds[] = 'pr_cascade = 1';
}
if( $this->level )
$conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
- if( !is_null($this->namespace) )
+ if( !is_null( $this->namespace ) )
$conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
return array(
'tables' => array( 'page_restrictions', 'page' ),
- 'fields' => 'pr_id,page_namespace,page_title,page_len,pr_type,pr_level,pr_expiry,pr_cascade',
+ 'fields' => array( 'pr_id', 'page_namespace', 'page_title', 'page_len',
+ 'pr_type', 'pr_level', 'pr_expiry', 'pr_cascade' ),
'conds' => $conds
);
}
diff --git a/includes/specials/SpecialProtectedtitles.php b/includes/specials/SpecialProtectedtitles.php
index a80f0d0a..0cba5ebd 100644
--- a/includes/specials/SpecialProtectedtitles.php
+++ b/includes/specials/SpecialProtectedtitles.php
@@ -29,7 +29,7 @@
class SpecialProtectedtitles extends SpecialPage {
protected $IdLevel = 'level';
- protected $IdType = 'type';
+ protected $IdType = 'type';
public function __construct() {
parent::__construct( 'Protectedtitles' );
@@ -76,11 +76,17 @@ class SpecialProtectedtitles extends SpecialPage {
static $infinity = null;
- if( is_null( $infinity ) ){
+ if( is_null( $infinity ) ) {
$infinity = wfGetDB( DB_SLAVE )->getInfinity();
}
$title = Title::makeTitleSafe( $row->pt_namespace, $row->pt_title );
+ if( !$title ) {
+ return Html::rawElement( 'li', array(),
+ Html::element( 'span', array( 'class' => 'mw-invalidtitle' ),
+ Linker::getInvalidTitleDescription( $this->getContext(), $row->pt_namespace, $row->pt_title ) ) ) . "\n";
+ }
+
$link = Linker::link( $title );
$description_items = array ();
@@ -113,7 +119,7 @@ class SpecialProtectedtitles extends SpecialPage {
* @return string
* @private
*/
- function showOptions( $namespace, $type='edit', $level ) {
+ function showOptions( $namespace, $type = 'edit', $level ) {
global $wgScript;
$action = htmlspecialchars( $wgScript );
$title = $this->getTitle();
@@ -161,13 +167,13 @@ class SpecialProtectedtitles extends SpecialPage {
// First pass to load the log names
foreach( $wgRestrictionLevels as $type ) {
- if ( $type !='' && $type !='*') {
+ if ( $type != '' && $type != '*' ) {
$text = $this->msg( "restriction-level-$type" )->text();
$m[$text] = $type;
}
}
// Is there only one level (aside from "all")?
- if( count($m) <= 2 ) {
+ if( count( $m ) <= 2 ) {
return '';
}
// Third pass generates sorted XHTML content
@@ -182,6 +188,10 @@ class SpecialProtectedtitles extends SpecialPage {
array( 'id' => $this->IdLevel, 'name' => $this->IdLevel ),
implode( "\n", $options ) );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
/**
@@ -191,7 +201,7 @@ class SpecialProtectedtitles extends SpecialPage {
class ProtectedTitlesPager extends AlphabeticPager {
public $mForm, $mConds;
- function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0 ) {
+ function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0 ) {
$this->mForm = $form;
$this->mConds = $conds;
$this->level = $level;
@@ -234,11 +244,12 @@ class ProtectedTitlesPager extends AlphabeticPager {
$conds[] = 'pt_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
if( $this->level )
$conds['pt_create_perm'] = $this->level;
- if( !is_null($this->namespace) )
+ if( !is_null( $this->namespace ) )
$conds[] = 'pt_namespace=' . $this->mDb->addQuotes( $this->namespace );
return array(
'tables' => 'protected_titles',
- 'fields' => 'pt_namespace,pt_title,pt_create_perm,pt_expiry,pt_timestamp',
+ 'fields' => array( 'pt_namespace', 'pt_title', 'pt_create_perm',
+ 'pt_expiry', 'pt_timestamp' ),
'conds' => $conds
);
}
@@ -247,4 +258,3 @@ class ProtectedTitlesPager extends AlphabeticPager {
return 'pt_timestamp';
}
}
-
diff --git a/includes/specials/SpecialRandompage.php b/includes/specials/SpecialRandompage.php
index 307088ed..b59f8349 100644
--- a/includes/specials/SpecialRandompage.php
+++ b/includes/specials/SpecialRandompage.php
@@ -28,11 +28,11 @@
* @ingroup SpecialPage
*/
class RandomPage extends SpecialPage {
- private $namespaces; // namespaces to select pages from
+ private $namespaces; // namespaces to select pages from
protected $isRedir = false; // should the result be a redirect?
protected $extra = array(); // Extra SQL statements
- public function __construct( $name = 'Randompage' ){
+ public function __construct( $name = 'Randompage' ) {
$this->namespaces = MWNamespace::getContentNamespaces();
parent::__construct( $name );
}
@@ -49,7 +49,7 @@ class RandomPage extends SpecialPage {
}
// select redirects instead of normal pages?
- public function isRedirect(){
+ public function isRedirect() {
return $this->isRedir;
}
@@ -159,4 +159,8 @@ class RandomPage extends SpecialPage {
return $dbr->fetchObject( $res );
}
+
+ protected function getGroupName() {
+ return 'redirects';
+ }
}
diff --git a/includes/specials/SpecialRandomredirect.php b/includes/specials/SpecialRandomredirect.php
index 88c81b31..51783a2f 100644
--- a/includes/specials/SpecialRandomredirect.php
+++ b/includes/specials/SpecialRandomredirect.php
@@ -28,7 +28,7 @@
* @ingroup SpecialPage
*/
class SpecialRandomredirect extends RandomPage {
- function __construct(){
+ function __construct() {
parent::__construct( 'Randomredirect' );
$this->isRedir = true;
}
diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php
index 2bd8b0a9..008678f7 100644
--- a/includes/specials/SpecialRecentchanges.php
+++ b/includes/specials/SpecialRecentchanges.php
@@ -42,16 +42,16 @@ class SpecialRecentChanges extends IncludableSpecialPage {
public function getDefaultOptions() {
$opts = new FormOptions();
- $opts->add( 'days', (int)$this->getUser()->getOption( 'rcdays' ) );
- $opts->add( 'limit', (int)$this->getUser()->getOption( 'rclimit' ) );
+ $opts->add( 'days', $this->getUser()->getIntOption( 'rcdays' ) );
+ $opts->add( 'limit', $this->getUser()->getIntOption( 'rclimit' ) );
$opts->add( 'from', '' );
- $opts->add( 'hideminor', $this->getUser()->getBoolOption( 'hideminor' ) );
- $opts->add( 'hidebots', true );
- $opts->add( 'hideanons', false );
- $opts->add( 'hideliu', false );
+ $opts->add( 'hideminor', $this->getUser()->getBoolOption( 'hideminor' ) );
+ $opts->add( 'hidebots', true );
+ $opts->add( 'hideanons', false );
+ $opts->add( 'hideliu', false );
$opts->add( 'hidepatrolled', $this->getUser()->getBoolOption( 'hidepatrolled' ) );
- $opts->add( 'hidemyself', false );
+ $opts->add( 'hidemyself', false );
$opts->add( 'namespace', '', FormOptions::INTNULL );
$opts->add( 'invert', false );
@@ -109,8 +109,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
public function feedSetup() {
global $wgFeedLimit;
$opts = $this->getDefaultOptions();
- # Feed is cached on limit,hideminor,namespace; other params would randomly not work
- $opts->fetchValuesFromRequest( $this->getRequest(), array( 'limit', 'hideminor', 'namespace' ) );
+ $opts->fetchValuesFromRequest( $this->getRequest() );
$opts->validateIntBounds( 'limit', 0, $wgFeedLimit );
return $opts;
}
@@ -130,7 +129,6 @@ class SpecialRecentChanges extends IncludableSpecialPage {
return $this->rcOptions;
}
-
/**
* Main execution point
*
@@ -156,7 +154,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
// Fetch results, prepare a batch link existence check query
$conds = $this->buildMainQueryConds( $opts );
$rows = $this->doMainQuery( $conds, $opts );
- if( $rows === false ){
+ if( $rows === false ) {
if( !$this->including() ) {
$this->doHeader( $opts );
}
@@ -187,7 +185,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
*
* @return Array
*/
- public function getFeedObject( $feedFormat ){
+ public function getFeedObject( $feedFormat ) {
$changesFeed = new ChangesFeed( $feedFormat, 'rcfeed' );
$formatter = $changesFeed->getFeedObject(
$this->msg( 'recentchanges' )->inContentLanguage()->text(),
@@ -233,7 +231,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
}
if( is_numeric( $bit ) ) {
- $opts['limit'] = $bit;
+ $opts['limit'] = $bit;
}
$m = array();
@@ -282,9 +280,9 @@ class SpecialRecentChanges extends IncludableSpecialPage {
# It makes no sense to hide both anons and logged-in users
# Where this occurs, force anons to be shown
$forcebot = false;
- if( $opts['hideanons'] && $opts['hideliu'] ){
+ if( $opts['hideanons'] && $opts['hideliu'] ) {
# Check if the user wants to show bots only
- if( $opts['hidebots'] ){
+ if( $opts['hidebots'] ) {
$opts['hideanons'] = false;
} else {
$forcebot = true;
@@ -297,9 +295,9 @@ class SpecialRecentChanges extends IncludableSpecialPage {
$cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400);
$cutoff = $dbr->timestamp( $cutoff_unixtime );
- $fromValid = preg_match('/^[0-9]{14}$/', $opts['from']);
- if( $fromValid && $opts['from'] > wfTimestamp(TS_MW,$cutoff) ) {
- $cutoff = $dbr->timestamp($opts['from']);
+ $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
+ if( $fromValid && $opts['from'] > wfTimestamp( TS_MW, $cutoff ) ) {
+ $cutoff = $dbr->timestamp( $opts['from'] );
} else {
$opts->reset( 'from' );
}
@@ -341,7 +339,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
if( $opts['namespace'] !== '' ) {
$selectedNS = $dbr->addQuotes( $opts['namespace'] );
$operator = $opts['invert'] ? '!=' : '=';
- $boolean = $opts['invert'] ? 'AND' : 'OR';
+ $boolean = $opts['invert'] ? 'AND' : 'OR';
# namespace association (bug 2429)
if( !$opts['associated'] ) {
@@ -352,8 +350,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
MWNamespace::getAssociated( $opts['namespace'] )
);
$condition = "(rc_namespace $operator $selectedNS "
- . $boolean
- . " rc_namespace $operator $associatedNS)";
+ . $boolean
+ . " rc_namespace $operator $associatedNS)";
}
$conds[] = $condition;
@@ -382,19 +380,22 @@ class SpecialRecentChanges extends IncludableSpecialPage {
$invert = $opts['invert'];
$associated = $opts['associated'];
- $fields = array( $dbr->tableName( 'recentchanges' ) . '.*' ); // all rc columns
+ $fields = RecentChange::selectFields();
// JOIN on watchlist for users
if ( $uid ) {
$tables[] = 'watchlist';
$fields[] = 'wl_user';
$fields[] = 'wl_notificationtimestamp';
- $join_conds['watchlist'] = array('LEFT JOIN',
- "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace");
+ $join_conds['watchlist'] = array( 'LEFT JOIN', array(
+ 'wl_user' => $uid,
+ 'wl_title=rc_title',
+ 'wl_namespace=rc_namespace'
+ ));
}
if ( $this->getUser()->isAllowed( 'rollback' ) ) {
$tables[] = 'page';
$fields[] = 'page_latest';
- $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+ $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
}
// Tag stuff.
ChangeTags::modifyDisplayQuery(
@@ -467,7 +468,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
/**
* Send output to the OutputPage object, only called if not used feeds
*
- * @param $rows Array of database rows
+ * @param array $rows of database rows
* @param $opts FormOptions
*/
public function webOutput( $rows, $opts ) {
@@ -481,7 +482,12 @@ class SpecialRecentChanges extends IncludableSpecialPage {
}
// And now for the content
- $this->getOutput()->setFeedAppendQuery( $this->getFeedQuery() );
+ $feedQuery = $this->getFeedQuery();
+ if ( $feedQuery !== '' ) {
+ $this->getOutput()->setFeedAppendQuery( $feedQuery );
+ } else {
+ $this->getOutput()->setFeedAppendQuery( false );
+ }
if( $wgAllowCategorizedRecentChanges ) {
$this->filterByCategories( $rows, $opts );
@@ -525,8 +531,12 @@ class SpecialRecentChanges extends IncludableSpecialPage {
}
$rc->numberofWatchingusers = $watcherCache[$obj->rc_namespace][$obj->rc_title];
}
- $s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ), $counter );
- --$limit;
+
+ $changeLine = $list->recentChangesLine( $rc, !empty( $obj->wl_user ), $counter );
+ if ( $changeLine !== false ) {
+ $s .= $changeLine;
+ --$limit;
+ }
}
$s .= $list->endRecentChangesList();
$this->getOutput()->addHTML( $s );
@@ -534,11 +544,24 @@ class SpecialRecentChanges extends IncludableSpecialPage {
/**
* Get the query string to append to feed link URLs.
- * This is overridden by RCL to add the target parameter
- * @return bool
+ *
+ * @return string
*/
public function getFeedQuery() {
- return false;
+ global $wgFeedLimit;
+
+ $this->getOptions()->validateIntBounds( 'limit', 0, $wgFeedLimit );
+ $options = $this->getOptions()->getChangedValues();
+
+ // wfArrayToCgi() omits options set to null or false
+ foreach ( $options as &$value ) {
+ if ( $value === false ) {
+ $value = '0';
+ }
+ }
+ unset( $value );
+
+ return wfArrayToCgi( $options );
}
/**
@@ -701,11 +724,11 @@ class SpecialRecentChanges extends IncludableSpecialPage {
/**
* Filter $rows by categories set in $opts
*
- * @param $rows Array of database rows
+ * @param array $rows of database rows
* @param $opts FormOptions
*/
function filterByCategories( &$rows, FormOptions $opts ) {
- $categories = array_map( 'trim', explode( '|' , $opts['categories'] ) );
+ $categories = array_map( 'trim', explode( '|', $opts['categories'] ) );
if( !count( $categories ) ) {
return;
@@ -766,8 +789,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
* Makes change an option link which carries all the other options
*
* @param $title Title
- * @param $override Array: options to override
- * @param $options Array: current options
+ * @param array $override options to override
+ * @param array $options current options
* @param $active Boolean: whether to show the link in bold
* @return string
*/
@@ -839,7 +862,6 @@ class SpecialRecentChanges extends IncludableSpecialPage {
}
$dl = $lang->pipeList( $dl );
-
// show/hide links
$showhide = array( $this->msg( 'show' )->text(), $this->msg( 'hide' )->text() );
$filters = array(
@@ -885,4 +907,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
'mediawiki.special.recentchanges',
) );
}
+
+ protected function getGroupName() {
+ return 'changes';
+ }
}
diff --git a/includes/specials/SpecialRecentchangeslinked.php b/includes/specials/SpecialRecentchangeslinked.php
index 862736d3..391c4a7f 100644
--- a/includes/specials/SpecialRecentchangeslinked.php
+++ b/includes/specials/SpecialRecentchangeslinked.php
@@ -29,7 +29,7 @@
class SpecialRecentchangeslinked extends SpecialRecentChanges {
var $rclTargetTitle;
- function __construct(){
+ function __construct() {
parent::__construct( 'Recentchangeslinked' );
}
@@ -37,7 +37,6 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
$opts = parent::getDefaultOptions();
$opts->add( 'target', '' );
$opts->add( 'showlinkedto', false );
- $opts->add( 'tagfilter', '' );
return $opts;
}
@@ -51,7 +50,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
return $opts;
}
- public function getFeedObject( $feedFormat ){
+ public function getFeedObject( $feedFormat ) {
$feed = new ChangesFeed( $feedFormat, false );
$feedObj = $feed->getFeedObject(
$this->msg( 'recentchangeslinked-title', $this->getTargetTitle()->getPrefixedText() )
@@ -72,7 +71,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
}
$outputPage = $this->getOutput();
$title = Title::newFromURL( $target );
- if( !$title || $title->getInterwiki() != '' ){
+ if( !$title || $title->getInterwiki() != '' ) {
$outputPage->wrapWikiMsg( "<div class=\"errorbox\">\n$1\n</div><br style=\"clear: both\" />", 'allpagesbadtitle' );
return false;
}
@@ -94,7 +93,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
$dbkey = $title->getDBkey();
$tables = array( 'recentchanges' );
- $select = array( $dbr->tableName( 'recentchanges' ) . '.*' );
+ $select = RecentChange::selectFields();
$join_conds = array();
$query_options = array();
@@ -103,11 +102,15 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
if( $uid ) {
$tables[] = 'watchlist';
$select[] = 'wl_user';
- $join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" );
+ $join_conds['watchlist'] = array( 'LEFT JOIN', array(
+ 'wl_user' => $uid,
+ 'wl_title=rc_title',
+ 'wl_namespace=rc_namespace'
+ ));
}
if ( $this->getUser()->isAllowed( 'rollback' ) ) {
$tables[] = 'page';
- $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+ $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
$select[] = 'page_latest';
}
ChangeTags::modifyDisplayQuery(
@@ -125,7 +128,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
if( $ns == NS_CATEGORY && !$showlinkedto ) {
// special handling for categories
- // XXX: should try to make this less klugy
+ // XXX: should try to make this less kludgy
$link_tables = array( 'categorylinks' );
$showlinkedto = true;
} else {
@@ -176,7 +179,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
$subconds["rc_namespace"] = $link_ns;
$subjoin = "rc_title = {$pfx}_to";
} else {
- $subjoin = "rc_namespace = {$pfx}_namespace AND rc_title = {$pfx}_title";
+ $subjoin = array( "rc_namespace = {$pfx}_namespace", "rc_title = {$pfx}_title" );
}
}
@@ -201,15 +204,15 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
$subsql[] = $query;
}
- if( count($subsql) == 0 ) {
+ if( count( $subsql ) == 0 ) {
return false; // should never happen
}
- if( count($subsql) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
+ if( count( $subsql ) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
$sql = $subsql[0];
} else {
// need to resort and relimit after union
- $sql = $dbr->unionQueries($subsql, false).' ORDER BY rc_timestamp DESC';
- $sql = $dbr->limitResult($sql, $limit, false);
+ $sql = $dbr->unionQueries( $subsql, false ) . ' ORDER BY rc_timestamp DESC';
+ $sql = $dbr->limitResult( $sql, $limit, false );
}
$res = $dbr->query( $sql, __METHOD__ );
@@ -225,16 +228,16 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
* @param $opts FormOptions
* @return array
*/
- function getExtraOptions( $opts ){
+ function getExtraOptions( $opts ) {
$opts->consumeValues( array( 'showlinkedto', 'target', 'tagfilter' ) );
$extraOpts = array();
$extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
$extraOpts['target'] = array( $this->msg( 'recentchangeslinked-page' )->escaped(),
- Xml::input( 'target', 40, str_replace('_',' ',$opts['target']) ) .
- Xml::check( 'showlinkedto', $opts['showlinkedto'], array('id' => 'showlinkedto') ) . ' ' .
+ Xml::input( 'target', 40, str_replace( '_', ' ', $opts['target'] ) ) .
+ Xml::check( 'showlinkedto', $opts['showlinkedto'], array( 'id' => 'showlinkedto' ) ) . ' ' .
Xml::label( $this->msg( 'recentchangeslinked-to' )->text(), 'showlinkedto' ) );
$tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
- if ($tagFilter) {
+ if ( $tagFilter ) {
$extraOpts['tagfilter'] = $tagFilter;
}
return $extraOpts;
@@ -262,15 +265,6 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
}
}
- public function getFeedQuery() {
- $target = $this->getTargetTitle();
- if( $target ) {
- return "target=" . urlencode( $target->getPrefixedDBkey() );
- } else {
- return false;
- }
- }
-
function setBottomText( FormOptions $opts ) {
if( isset( $this->mResultEmpty ) && $this->mResultEmpty ) {
$this->getOutput()->addWikiMsg( 'recentchangeslinked-noresult' );
diff --git a/includes/specials/SpecialRevisiondelete.php b/includes/specials/SpecialRevisiondelete.php
index aba90cf8..5a5f8ffb 100644
--- a/includes/specials/SpecialRevisiondelete.php
+++ b/includes/specials/SpecialRevisiondelete.php
@@ -133,7 +133,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
$this->ids = explode( ',', $ids );
} else {
# Array input
- $this->ids = array_keys( $request->getArray('ids',array()) );
+ $this->ids = array_keys( $request->getArray( 'ids', array() ) );
}
// $this->ids = array_map( 'intval', $this->ids );
$this->ids = array_unique( array_filter( $this->ids ) );
@@ -147,7 +147,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
} else {
$this->typeName = $request->getVal( 'type' );
$this->targetObj = Title::newFromText( $request->getText( 'target' ) );
- if ( $this->targetObj->isSpecial( 'Log' ) ) {
+ if ( $this->targetObj && $this->targetObj->isSpecial( 'Log' ) && count( $this->ids ) !== 0 ) {
$result = wfGetDB( DB_SLAVE )->select( 'logging',
'log_type',
array( 'log_id' => $this->ids ),
@@ -155,14 +155,9 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
array( 'DISTINCT' )
);
- $logTypes = array();
- foreach ( $result as $row ) {
- $logTypes[] = $row->log_type;
- }
-
- if ( count( $logTypes ) == 1 ) {
+ if ( $result->numRows() == 1 ) {
// If there's only one type, the target can be set to include it.
- $this->targetObj = SpecialPage::getTitleFor( 'Log', $logTypes[0] );
+ $this->targetObj = SpecialPage::getTitleFor( 'Log', $result->current()->log_type );
}
}
}
@@ -196,7 +191,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
$this->otherReason = $request->getVal( 'wpReason' );
# We need a target page!
- if( is_null($this->targetObj) ) {
+ if( is_null( $this->targetObj ) ) {
$output->addWikiMsg( 'undelete-header' );
return;
}
@@ -209,7 +204,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER )
);
- if( $user->isAllowed('suppressrevision') ) {
+ if( $user->isAllowed( 'suppressrevision' ) ) {
$this->checks[] = array( 'revdelete-hide-restricted',
'wpHideRestricted', Revision::DELETED_RESTRICTED );
}
@@ -230,7 +225,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
# Show relevant lines from the suppression log
if( $user->isAllowed( 'suppressionlog' ) ) {
$suppressLogPage = new LogPage( 'suppress' );
- $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" );
+ $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" );
LogEventsList::showLogExtract( $output, 'suppress',
$this->targetObj, '', array( 'lim' => 25, 'conds' => $qc ) );
}
@@ -258,7 +253,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
array( 'action' => 'history' )
);
# Link to deleted edits
- if( $this->getUser()->isAllowed('undelete') ) {
+ if( $this->getUser()->isAllowed( 'undelete' ) ) {
$undelete = SpecialPage::getTitleFor( 'Undelete' );
$links[] = Linker::linkKnown(
$undelete,
@@ -361,7 +356,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
$UserAllowed = true;
if ( $this->typeName == 'logging' ) {
- $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count($this->ids) ) );
+ $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count( $this->ids ) ) );
} else {
$this->getOutput()->addWikiMsg( 'revdelete-selected',
$this->targetObj->getPrefixedText(), count( $this->ids ) );
@@ -469,8 +464,8 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
}
/**
- * @return String: HTML
- */
+ * @return String: HTML
+ */
protected function buildCheckBoxes() {
$html = '<table>';
// If there is just one item, use checkboxes
@@ -522,11 +517,12 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
/**
* UI entry point for form submission.
+ * @throws PermissionsError
* @return bool
*/
protected function submit() {
# Check edit token on submission
- $token = $this->getRequest()->getVal('wpEditToken');
+ $token = $this->getRequest()->getVal( 'wpEditToken' );
if( $this->submitClicked && !$this->getUser()->matchEditToken( $token ) ) {
$this->getOutput()->addWikiMsg( 'sessionfailure' );
return false;
@@ -541,7 +537,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
$comment = $this->otherReason;
}
# Can the user set this field?
- if( $bitParams[Revision::DELETED_RESTRICTED]==1 && !$this->getUser()->isAllowed('suppressrevision') ) {
+ if( $bitParams[Revision::DELETED_RESTRICTED] == 1 && !$this->getUser()->isAllowed( 'suppressrevision' ) ) {
throw new PermissionsError( 'suppressrevision' );
}
# If the save went through, go to success message...
@@ -583,14 +579,14 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
protected function extractBitParams() {
$bitfield = array();
foreach( $this->checks as $item ) {
- list( /* message */ , $name, $field ) = $item;
+ list( /* message */, $name, $field ) = $item;
$val = $this->getRequest()->getInt( $name, 0 /* unchecked */ );
if( $val < -1 || $val > 1) {
$val = -1; // -1 for existing value
}
$bitfield[$field] = $val;
}
- if( !isset($bitfield[Revision::DELETED_RESTRICTED]) ) {
+ if( !isset( $bitfield[Revision::DELETED_RESTRICTED] ) ) {
$bitfield[Revision::DELETED_RESTRICTED] = 0;
}
return $bitfield;
@@ -598,8 +594,8 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
/**
* Put together a rev_deleted bitfield
- * @param $bitPars array extractBitParams() params
- * @param $oldfield int current bitfield
+ * @param array $bitPars extractBitParams() params
+ * @param int $oldfield current bitfield
* @return array
*/
public static function extractBitfield( $bitPars, $oldfield ) {
@@ -627,5 +623,8 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
array( 'value' => $bitfield, 'comment' => $reason )
);
}
-}
+ protected function getGroupName() {
+ return 'pagetools';
+ }
+}
diff --git a/includes/specials/SpecialSearch.php b/includes/specials/SpecialSearch.php
index 5f5b6b4d..6c401486 100644
--- a/includes/specials/SpecialSearch.php
+++ b/includes/specials/SpecialSearch.php
@@ -78,7 +78,7 @@ class SpecialSearch extends SpecialPage {
/**
* Entry point
*
- * @param $par String or null
+ * @param string $par or null
*/
public function execute( $par ) {
$this->setHeaders();
@@ -138,7 +138,7 @@ class SpecialSearch extends SpecialPage {
// BC with old request format
$profile = 'advanced';
foreach( $profiles as $key => $data ) {
- if ( $nslist === $data['namespaces'] && $key !== 'advanced') {
+ if ( $nslist === $data['namespaces'] && $key !== 'advanced' ) {
$profile = $key;
}
}
@@ -159,7 +159,7 @@ class SpecialSearch extends SpecialPage {
$default = $request->getBool( 'profile' ) ? 0 : 1;
$this->searchRedirects = $request->getBool( 'redirs', $default ) ? 1 : 0;
$this->didYouMeanHtml = ''; # html of did you mean... link
- $this->fulltext = $request->getVal('fulltext');
+ $this->fulltext = $request->getVal( 'fulltext' );
$this->profile = $profile;
}
@@ -218,7 +218,7 @@ class SpecialSearch extends SpecialPage {
$search->showRedirects = $this->searchRedirects; // BC
$search->setFeatureData( 'list-redirects', $this->searchRedirects );
$search->prefix = $this->mPrefix;
- $term = $search->transformSearchTerm($term);
+ $term = $search->transformSearchTerm( $term );
wfRunHooks( 'SpecialSearchSetupEngine', array( $this, $this->profile, $search ) );
@@ -250,7 +250,7 @@ class SpecialSearch extends SpecialPage {
$t = Title::newFromText( $term );
// fetch search results
- $rewritten = $search->replacePrefixes($term);
+ $rewritten = $search->replacePrefixes( $term );
$titleMatches = $search->searchTitle( $rewritten );
if( !( $titleMatches instanceof SearchResultTooMany ) ) {
@@ -261,7 +261,7 @@ class SpecialSearch extends SpecialPage {
if( $textMatches && $textMatches->hasSuggestion() ) {
$st = SpecialPage::getTitleFor( 'Search' );
- # mirror Go/Search behaviour of original request ..
+ # mirror Go/Search behavior of original request ..
$didYouMeanParams = array( 'search' => $textMatches->getSuggestionQuery() );
if( $this->fulltext != null ) {
@@ -288,6 +288,13 @@ class SpecialSearch extends SpecialPage {
$this->didYouMeanHtml = '<div class="searchdidyoumean">' . $this->msg( 'search-suggest' )->rawParams( $suggestLink )->text() . '</div>';
}
+
+ if ( !wfRunHooks( 'SpecialSearchResultsPrepend', array( $this, $out, $term ) ) ) {
+ # Hook requested termination
+ wfProfileOut( __METHOD__ );
+ return;
+ }
+
// start rendering the page
$out->addHtml(
Xml::openElement(
@@ -304,9 +311,9 @@ class SpecialSearch extends SpecialPage {
Xml::openElement( 'tr' ) .
Xml::openElement( 'td' ) . "\n" .
$this->shortDialog( $term ) .
- Xml::closeElement('td') .
- Xml::closeElement('tr') .
- Xml::closeElement('table')
+ Xml::closeElement( 'td' ) .
+ Xml::closeElement( 'tr' ) .
+ Xml::closeElement( 'table' )
);
// Sometimes the search engine knows there are too many hits
@@ -316,7 +323,7 @@ class SpecialSearch extends SpecialPage {
return;
}
- $filePrefix = $wgContLang->getFormattedNsText(NS_FILE).':';
+ $filePrefix = $wgContLang->getFormattedNsText( NS_FILE ) . ':';
if( trim( $term ) === '' || $filePrefix === trim( $term ) ) {
$out->addHTML( $this->formHeader( $term, 0, 0 ) );
$out->addHtml( $this->getProfileForm( $this->profile, $term ) );
@@ -340,16 +347,15 @@ class SpecialSearch extends SpecialPage {
// get total number of results if backend can calculate it
$totalRes = 0;
- if($titleMatches && !is_null( $titleMatches->getTotalHits() ) )
+ if( $titleMatches && !is_null( $titleMatches->getTotalHits() ) )
$totalRes += $titleMatches->getTotalHits();
- if($textMatches && !is_null( $textMatches->getTotalHits() ))
+ if( $textMatches && !is_null( $textMatches->getTotalHits() ) )
$totalRes += $textMatches->getTotalHits();
// show number of results and current offset
$out->addHTML( $this->formHeader( $term, $num, $totalRes ) );
$out->addHtml( $this->getProfileForm( $this->profile, $term ) );
-
$out->addHtml( Xml::closeElement( 'form' ) );
$out->addHtml( "<div class='searchresults'>" );
@@ -404,6 +410,7 @@ class SpecialSearch extends SpecialPage {
if( $num || $this->offset ) {
$out->addHTML( "<p class='mw-search-pager-bottom'>{$prevnext}</p>\n" );
}
+ wfRunHooks( 'SpecialSearchResultsAppend', array( $this, $out, $term ) );
wfProfileOut( __METHOD__ );
}
@@ -423,7 +430,7 @@ class SpecialSearch extends SpecialPage {
if( $t->isKnown() ) {
$messageName = 'searchmenu-exists';
- } elseif( $t->userCan( 'create' ) ) {
+ } elseif( $t->userCan( 'create', $this->getUser() ) ) {
$messageName = 'searchmenu-new';
} else {
$messageName = 'searchmenu-new-nocreate';
@@ -447,9 +454,11 @@ class SpecialSearch extends SpecialPage {
# Should advanced UI be used?
$this->searchAdvanced = ($this->profile === 'advanced');
$out = $this->getOutput();
- if( strval( $term ) !== '' ) {
+ if( strval( $term ) !== '' ) {
$out->setPageTitle( $this->msg( 'searchresults' ) );
- $out->setHTMLTitle( $this->msg( 'pagetitle', $this->msg( 'searchresults-title', $term )->plain() ) );
+ $out->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams(
+ $this->msg( 'searchresults-title' )->rawParams( $term )->text()
+ ) );
}
// add javascript specific to special:search
$out->addModules( 'mediawiki.special.search' );
@@ -506,7 +515,7 @@ class SpecialSearch extends SpecialPage {
$out = "";
$infoLine = $matches->getInfo();
- if( !is_null($infoLine) ) {
+ if( !is_null( $infoLine ) ) {
$out .= "\n<!-- {$infoLine} -->\n";
}
$out .= "<ul class='mw-search-results'>\n";
@@ -527,7 +536,7 @@ class SpecialSearch extends SpecialPage {
* Format a single hit result
*
* @param $result SearchResult
- * @param $terms Array: terms to highlight
+ * @param array $terms terms to highlight
*
* @return string
*/
@@ -541,7 +550,7 @@ class SpecialSearch extends SpecialPage {
$t = $result->getTitle();
- $titleSnippet = $result->getTitleSnippet($terms);
+ $titleSnippet = $result->getTitleSnippet( $terms );
if( $titleSnippet == '' )
$titleSnippet = null;
@@ -559,7 +568,7 @@ class SpecialSearch extends SpecialPage {
//If page content is not readable, just return the title.
//This is not quite safe, but better than showing excerpts from non-readable pages
//Note that hiding the entry entirely would screw up paging.
- if( !$t->userCan( 'read' ) ) {
+ if( !$t->userCan( 'read', $this->getUser() ) ) {
wfProfileOut( __METHOD__ );
return "<li>{$link}</li>\n";
}
@@ -574,12 +583,12 @@ class SpecialSearch extends SpecialPage {
// format redirects / relevant sections
$redirectTitle = $result->getRedirectTitle();
- $redirectText = $result->getRedirectSnippet($terms);
+ $redirectText = $result->getRedirectSnippet( $terms );
$sectionTitle = $result->getSectionTitle();
- $sectionText = $result->getSectionSnippet($terms);
+ $sectionText = $result->getSectionSnippet( $terms );
$redirect = '';
- if( !is_null($redirectTitle) ) {
+ if( !is_null( $redirectTitle ) ) {
if( $redirectText == '' )
$redirectText = null;
@@ -591,7 +600,7 @@ class SpecialSearch extends SpecialPage {
$section = '';
- if( !is_null($sectionTitle) ) {
+ if( !is_null( $sectionTitle ) ) {
if( $sectionText == '' )
$sectionText = null;
@@ -602,7 +611,7 @@ class SpecialSearch extends SpecialPage {
}
// format text extract
- $extract = "<div class='searchresult'>".$result->getTextSnippet($terms)."</div>";
+ $extract = "<div class='searchresult'>" . $result->getTextSnippet( $terms ) . "</div>";
$lang = $this->getLanguage();
@@ -667,7 +676,7 @@ class SpecialSearch extends SpecialPage {
return "<li>" .
'<table class="searchResultImage">' .
'<tr>' .
- '<td width="120" style="text-align: center; vertical-align: top;">' .
+ '<td style="width: 120px; text-align: center; vertical-align: top;">' .
$thumb->toHtml( array( 'desc-link' => true ) ) .
'</td>' .
'<td style="vertical-align: top;">' .
@@ -682,11 +691,21 @@ class SpecialSearch extends SpecialPage {
}
}
- wfProfileOut( __METHOD__ );
- return "<li><div class='mw-search-result-heading'>{$link} {$redirect} {$section}</div> {$extract}\n" .
- "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
- "</li>\n";
+ $html = null;
+
+ if ( wfRunHooks( 'ShowSearchHit', array (
+ $this, $result, $terms,
+ &$link, &$redirect, &$section, &$extract,
+ &$score, &$size, &$date, &$related,
+ &$html
+ ) ) ) {
+ $html = "<li><div class='mw-search-result-heading'>{$link} {$redirect} {$section}</div> {$extract}\n" .
+ "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
+ "</li>\n";
+ }
+ wfProfileOut( __METHOD__ );
+ return $html;
}
/**
@@ -703,16 +722,17 @@ class SpecialSearch extends SpecialPage {
$terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
$out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>".
- $this->msg( 'search-interwiki-caption' )->text() . "</div>\n";
+ $this->msg( 'search-interwiki-caption' )->text() . "</div>\n";
$out .= "<ul class='mw-search-iwresults'>\n";
// work out custom project captions
$customCaptions = array();
$customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() ); // format per line <iwprefix>:<caption>
- foreach($customLines as $line) {
- $parts = explode(":",$line,2);
- if(count($parts) == 2) // validate line
+ foreach( $customLines as $line ) {
+ $parts = explode( ":", $line, 2 );
+ if( count( $parts ) == 2 ) { // validate line
$customCaptions[$parts[0]] = $parts[1];
+ }
}
$prev = null;
@@ -738,7 +758,7 @@ class SpecialSearch extends SpecialPage {
* @param $lastInterwiki String
* @param $terms Array
* @param $query String
- * @param $customCaptions Array: iw prefix -> caption
+ * @param array $customCaptions iw prefix -> caption
*
* @return string
*/
@@ -752,7 +772,7 @@ class SpecialSearch extends SpecialPage {
$t = $result->getTitle();
- $titleSnippet = $result->getTitleSnippet($terms);
+ $titleSnippet = $result->getTitleSnippet( $terms );
if( $titleSnippet == '' )
$titleSnippet = null;
@@ -764,9 +784,9 @@ class SpecialSearch extends SpecialPage {
// format redirect if any
$redirectTitle = $result->getRedirectTitle();
- $redirectText = $result->getRedirectSnippet($terms);
+ $redirectText = $result->getRedirectSnippet( $terms );
$redirect = '';
- if( !is_null($redirectTitle) ) {
+ if( !is_null( $redirectTitle ) ) {
if( $redirectText == '' )
$redirectText = null;
@@ -778,8 +798,8 @@ class SpecialSearch extends SpecialPage {
$out = "";
// display project name
- if(is_null($lastInterwiki) || $lastInterwiki != $t->getInterwiki()) {
- if( array_key_exists($t->getInterwiki(),$customCaptions) ) {
+ if( is_null( $lastInterwiki ) || $lastInterwiki != $t->getInterwiki() ) {
+ if( array_key_exists( $t->getInterwiki(), $customCaptions ) ) {
// captions from 'search-interwiki-custom'
$caption = $customCaptions[$t->getInterwiki()];
} else {
@@ -789,7 +809,7 @@ class SpecialSearch extends SpecialPage {
$caption = $this->msg( 'search-interwiki-default', $parsed['host'] )->text();
}
// "more results" link (special page stuff could be localized, but we might not know target lang)
- $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search");
+ $searchTitle = Title::newFromText( $t->getInterwiki() . ":Special:Search" );
$searchLink = Linker::linkKnown(
$searchTitle,
$this->msg( 'search-interwiki-more' )->text(),
@@ -831,7 +851,7 @@ class SpecialSearch extends SpecialPage {
/**
* Generates the power search box at [[Special:Search]]
*
- * @param $term String: search term
+ * @param string $term search term
* @param $opts array
* @return String: HTML form
*/
@@ -897,7 +917,7 @@ class SpecialSearch extends SpecialPage {
'fieldset',
array( 'id' => 'mw-searchoptions', 'style' => 'margin:0em;' )
) .
- Xml::element( 'legend', null, $this->msg('powersearch-legend' )->text() ) .
+ Xml::element( 'legend', null, $this->msg( 'powersearch-legend' )->text() ) .
Xml::tags( 'h4', null, $this->msg( 'powersearch-ns' )->parse() ) .
Html::element( 'div', array( 'id' => 'mw-search-togglebox' ) ) .
Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
@@ -964,7 +984,7 @@ class SpecialSearch extends SpecialPage {
* @return string
*/
protected function formHeader( $term, $resultsShown, $totalNum ) {
- $out = Xml::openElement('div', array( 'class' => 'mw-search-formheader' ) );
+ $out = Xml::openElement( 'div', array( 'class' => 'mw-search-formheader' ) );
$bareterm = $term;
if( $this->startsWithImage( $term ) ) {
@@ -1001,11 +1021,11 @@ class SpecialSearch extends SpecialPage {
);
}
$out .= Xml::closeElement( 'ul' );
- $out .= Xml::closeElement('div') ;
+ $out .= Xml::closeElement( 'div' );
// Results-info
if ( $resultsShown > 0 ) {
- if ( $totalNum > 0 ){
+ if ( $totalNum > 0 ) {
$top = $this->msg( 'showingresultsheader' )
->numParams( $this->offset + 1, $this->offset + $resultsShown, $totalNum )
->params( wfEscapeWikiText( $term ) )
@@ -1026,7 +1046,7 @@ class SpecialSearch extends SpecialPage {
}
$out .= Xml::element( 'div', array( 'style' => 'clear:both' ), '', false );
- $out .= Xml::closeElement('div');
+ $out .= Xml::closeElement( 'div' );
return $out;
}
@@ -1053,10 +1073,10 @@ class SpecialSearch extends SpecialPage {
* Make a search link with some target namespaces
*
* @param $term String
- * @param $namespaces Array ignored
- * @param $label String: link's text
- * @param $tooltip String: link's tooltip
- * @param $params Array: query string parameters
+ * @param array $namespaces ignored
+ * @param string $label link's text
+ * @param string $tooltip link's tooltip
+ * @param array $params query string parameters
* @return String: HTML fragment
*/
protected function makeSearchLink( $term, $namespaces, $label, $tooltip, $params = array() ) {
@@ -1086,7 +1106,7 @@ class SpecialSearch extends SpecialPage {
/**
* Check if query starts with image: prefix
*
- * @param $term String: the string to check
+ * @param string $term the string to check
* @return Boolean
*/
protected function startsWithImage( $term ) {
@@ -1102,7 +1122,7 @@ class SpecialSearch extends SpecialPage {
/**
* Check if query starts with all: prefix
*
- * @param $term String: the string to check
+ * @param string $term the string to check
* @return Boolean
*/
protected function startsWithAll( $term ) {
@@ -1111,7 +1131,7 @@ class SpecialSearch extends SpecialPage {
$p = explode( ':', $term );
if( count( $p ) > 1 ) {
- return $p[0] == $allkeyword;
+ return $p[0] == $allkeyword;
}
return false;
}
@@ -1141,4 +1161,7 @@ class SpecialSearch extends SpecialPage {
$this->extraParams[$key] = $value;
}
+ protected function getGroupName() {
+ return 'redirects';
+ }
}
diff --git a/includes/specials/SpecialShortpages.php b/includes/specials/SpecialShortpages.php
index 5a4e8f03..1be7fbed 100644
--- a/includes/specials/SpecialShortpages.php
+++ b/includes/specials/SpecialShortpages.php
@@ -110,4 +110,8 @@ class ShortPagesPage extends QueryPage {
? "${hlinkInParentheses} {$dm}{$plink} {$dm}[{$size}]"
: "<del>${hlinkInParentheses} {$dm}{$plink} {$dm}[{$size}]</del>";
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialSpecialpages.php b/includes/specials/SpecialSpecialpages.php
index e973ddc8..57fffb84 100644
--- a/includes/specials/SpecialSpecialpages.php
+++ b/includes/specials/SpecialSpecialpages.php
@@ -62,11 +62,15 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
$groups = array();
foreach ( $pages as $page ) {
if ( $page->isListed() ) {
- $group = SpecialPageFactory::getGroup( $page );
+ $group = $page->getFinalGroupName();
if( !isset( $groups[$group] ) ) {
$groups[$group] = array();
}
- $groups[$group][$page->getDescription()] = array( $page->getTitle(), $page->isRestricted(), $page->isExpensive() );
+ $groups[$group][$page->getDescription()] = array(
+ $page->getTitle(),
+ $page->isRestricted(),
+ $page->isCached()
+ );
}
}
@@ -88,15 +92,14 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
}
private function outputPageList( $groups ) {
- global $wgMiserMode;
$out = $this->getOutput();
$includesRestrictedPages = false;
$includesCachedPages = false;
foreach ( $groups as $group => $sortedPages ) {
- $middle = ceil( count( $sortedPages )/2 );
$total = count( $sortedPages );
+ $middle = ceil( $total / 2 );
$count = 0;
$out->wrapWikiMsg( "<h2 class=\"mw-specialpagesgroup\" id=\"mw-specialpagesgroup-$group\">$1</h2>\n", "specialpages-group-$group" );
@@ -107,10 +110,10 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
Html::openElement( 'ul' ) . "\n"
);
foreach( $sortedPages as $desc => $specialpage ) {
- list( $title, $restricted, $expensive) = $specialpage;
+ list( $title, $restricted, $cached ) = $specialpage;
$pageClasses = array();
- if ( $expensive && $wgMiserMode ){
+ if ( $cached ) {
$includesCachedPages = true;
$pageClasses[] = 'mw-specialpagecached';
}
@@ -119,7 +122,7 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
$pageClasses[] = 'mw-specialpagerestricted';
}
- $link = Linker::linkKnown( $title , htmlspecialchars( $desc ) );
+ $link = Linker::linkKnown( $title, htmlspecialchars( $desc ) );
$out->addHTML( Html::rawElement( 'li', array( 'class' => implode( ' ', $pageClasses ) ), $link ) . "\n" );
# Split up the larger groups
diff --git a/includes/specials/SpecialStatistics.php b/includes/specials/SpecialStatistics.php
index 46881ec4..ee768263 100644
--- a/includes/specials/SpecialStatistics.php
+++ b/includes/specials/SpecialStatistics.php
@@ -61,7 +61,7 @@ class SpecialStatistics extends SpecialPage {
if( !$wgMiserMode ) {
$key = wfMemcKey( 'sitestats', 'activeusers-updated' );
// Re-calculate the count if the last tally is old...
- if( !$wgMemc->get($key) ) {
+ if( !$wgMemc->get( $key ) ) {
$dbw = wfGetDB( DB_MASTER );
SiteStatsUpdate::cacheUpdate( $dbw );
$wgMemc->set( $key, '1', 24*3600 ); // don't update for 1 day
@@ -222,7 +222,7 @@ class SpecialStatistics extends SpecialPage {
}
$text .= $this->formatRow( $grouppage . ' ' . $grouplink,
$this->getLanguage()->formatNum( $countUsers ),
- array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero ) );
+ array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero ) );
}
return $text;
}
@@ -277,21 +277,60 @@ class SpecialStatistics extends SpecialPage {
return $text;
}
- private function getOtherStats( $stats ) {
- if ( !count( $stats ) )
- return '';
+ /**
+ * Conversion of external statistics into an internal representation
+ * Following a ([<header-message>][<item-message>] = number) pattern
+ *
+ * @param array $stats
+ * @return string
+ */
+ private function getOtherStats( array $stats ) {
+ $return = '';
- $return = Xml::openElement( 'tr' ) .
- Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-hooks' )->parse() ) .
- Xml::closeElement( 'tr' );
+ foreach( $stats as $header => $items ) {
+
+ // Identify the structure used
+ if ( is_array( $items ) ) {
- foreach( $stats as $name => $number ) {
- $name = htmlspecialchars( $name );
- $number = htmlspecialchars( $number );
+ // Ignore headers that are recursively set as legacy header
+ if ( $header !== 'statistics-header-hooks' ) {
+ $return .= $this->formatRowHeader( $header );
+ }
+
+ // Collect all items that belong to the same header
+ foreach( $items as $key => $value ) {
+ $name = $this->msg( $key )->parse();
+ $number = htmlspecialchars( $value );
+
+ $return .= $this->formatRow( $name, $this->getLanguage()->formatNum( $number ), array( 'class' => 'mw-statistics-hook' ) );
+ }
+ } else {
+ // Create the legacy header only once
+ if ( $return === '' ) {
+ $return .= $this->formatRowHeader( 'statistics-header-hooks' );
+ }
- $return .= $this->formatRow( $name, $this->getLanguage()->formatNum( $number ), array( 'class' => 'mw-statistics-hook' ) );
+ // Recursively remap the legacy structure
+ $return .= $this->getOtherStats( array( 'statistics-header-hooks' => array( $header => $items ) ) );
+ }
}
return $return;
}
+
+ /**
+ * Format row header
+ *
+ * @param string $header
+ * @return string
+ */
+ private function formatRowHeader( $header ) {
+ return Xml::openElement( 'tr' ) .
+ Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( $header )->parse() ) .
+ Xml::closeElement( 'tr' );
+ }
+
+ protected function getGroupName() {
+ return 'wiki';
+ }
}
diff --git a/includes/specials/SpecialTags.php b/includes/specials/SpecialTags.php
index 4036ebb2..6d161031 100644
--- a/includes/specials/SpecialTags.php
+++ b/includes/specials/SpecialTags.php
@@ -92,4 +92,8 @@ class SpecialTags extends SpecialPage {
return Xml::tags( 'tr', null, $newRow ) . "\n";
}
+
+ protected function getGroupName() {
+ return 'changes';
+ }
}
diff --git a/includes/specials/SpecialUnblock.php b/includes/specials/SpecialUnblock.php
index fb2005b5..c4a53cf0 100644
--- a/includes/specials/SpecialUnblock.php
+++ b/includes/specials/SpecialUnblock.php
@@ -32,11 +32,11 @@ class SpecialUnblock extends SpecialPage {
protected $type;
protected $block;
- public function __construct(){
+ public function __construct() {
parent::__construct( 'Unblock', 'block' );
}
- public function execute( $par ){
+ public function execute( $par ) {
$this->checkPermissions();
$this->checkReadOnly();
@@ -56,8 +56,8 @@ class SpecialUnblock extends SpecialPage {
$form->setSubmitTextMsg( 'ipusubmit' );
$form->addPreText( $this->msg( 'unblockiptext' )->parseAsBlock() );
- if( $form->show() ){
- switch( $this->type ){
+ if( $form->show() ) {
+ switch( $this->type ) {
case Block::TYPE_USER:
case Block::TYPE_IP:
$out->addWikiMsg( 'unblocked', wfEscapeWikiText( $this->target ) );
@@ -73,7 +73,7 @@ class SpecialUnblock extends SpecialPage {
}
}
- protected function getFields(){
+ protected function getFields() {
$fields = array(
'Target' => array(
'type' => 'text',
@@ -92,21 +92,21 @@ class SpecialUnblock extends SpecialPage {
)
);
- if( $this->block instanceof Block ){
+ if( $this->block instanceof Block ) {
list( $target, $type ) = $this->block->getTargetAndType();
# Autoblocks are logged as "autoblock #123 because the IP was recently used by
# User:Foo, and we've just got any block, auto or not, that applies to a target
# the user has specified. Someone could be fishing to connect IPs to autoblocks,
# so don't show any distinction between unblocked IPs and autoblocked IPs
- if( $type == Block::TYPE_AUTO && $this->type == Block::TYPE_IP ){
+ if( $type == Block::TYPE_AUTO && $this->type == Block::TYPE_IP ) {
$fields['Target']['default'] = $this->target;
unset( $fields['Name'] );
} else {
$fields['Target']['default'] = $target;
$fields['Target']['type'] = 'hidden';
- switch( $type ){
+ switch( $type ) {
case Block::TYPE_USER:
case Block::TYPE_IP:
$fields['Name']['default'] = Linker::link(
@@ -149,14 +149,15 @@ class SpecialUnblock extends SpecialPage {
*
* @param $data Array
* @param $context IContextSource
+ * @throws ErrorPageError
* @return Array( Array(message key, parameters) ) on failure, True on success
*/
- public static function processUnblock( array $data, IContextSource $context ){
+ public static function processUnblock( array $data, IContextSource $context ) {
$performer = $context->getUser();
$target = $data['Target'];
$block = Block::newFromTarget( $data['Target'] );
- if( !$block instanceof Block ){
+ if( !$block instanceof Block ) {
return array( array( 'ipb_cant_unblock', $target ) );
}
@@ -172,8 +173,8 @@ class SpecialUnblock extends SpecialPage {
# unblock the whole range.
list( $target, $type ) = SpecialBlock::getTargetAndType( $target );
if( $block->getType() == Block::TYPE_RANGE && $type == Block::TYPE_IP ) {
- $range = $block->getTarget();
- return array( array( 'ipb_blocked_as_range', $target, $range ) );
+ $range = $block->getTarget();
+ return array( array( 'ipb_blocked_as_range', $target, $range ) );
}
# If the name was hidden and the blocking user cannot hide
@@ -212,4 +213,8 @@ class SpecialUnblock extends SpecialPage {
return true;
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialUncategorizedcategories.php b/includes/specials/SpecialUncategorizedcategories.php
index 70d98df9..54b20dde 100644
--- a/includes/specials/SpecialUncategorizedcategories.php
+++ b/includes/specials/SpecialUncategorizedcategories.php
@@ -31,4 +31,17 @@ class UncategorizedCategoriesPage extends UncategorizedPagesPage {
parent::__construct( $name );
$this->requestedNamespace = NS_CATEGORY;
}
+
+ /**
+ * Formats the result
+ * @param $skin The current skin
+ * @param $result The query result
+ * @return string The category link
+ */
+ function formatResult ( $skin, $result ) {
+ $title = Title::makeTitle( NS_CATEGORY, $result->title );
+ $text = $title->getText();
+
+ return Linker::linkKnown( $title, htmlspecialchars( $text ) );
+ }
}
diff --git a/includes/specials/SpecialUncategorizedimages.php b/includes/specials/SpecialUncategorizedimages.php
index 5865bf62..53aa3f34 100644
--- a/includes/specials/SpecialUncategorizedimages.php
+++ b/includes/specials/SpecialUncategorizedimages.php
@@ -60,4 +60,7 @@ class UncategorizedImagesPage extends ImageQueryPage {
);
}
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUncategorizedpages.php b/includes/specials/SpecialUncategorizedpages.php
index 1226a6ca..b518e6fb 100644
--- a/includes/specials/SpecialUncategorizedpages.php
+++ b/includes/specials/SpecialUncategorizedpages.php
@@ -41,7 +41,10 @@ class UncategorizedPagesPage extends PageQueryPage {
function isExpensive() {
return true;
}
- function isSyndicated() { return false; }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -52,7 +55,7 @@ class UncategorizedPagesPage extends PageQueryPage {
// default for page_namespace is all content namespaces (if requestedNamespace is false)
// otherwise, page_namespace is requestedNamespace
'conds' => array ( 'cl_from IS NULL',
- 'page_namespace' => ( $this->requestedNamespace!==false ? $this->requestedNamespace : MWNamespace::getContentNamespaces() ),
+ 'page_namespace' => ( $this->requestedNamespace !== false ? $this->requestedNamespace : MWNamespace::getContentNamespaces() ),
'page_is_redirect' => 0 ),
'join_conds' => array ( 'categorylinks' => array (
'LEFT JOIN', 'cl_from = page_id' ) )
@@ -66,4 +69,8 @@ class UncategorizedPagesPage extends PageQueryPage {
return array( 'page_namespace', 'page_title' );
return array( 'page_title' );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php
index d8e0b97c..e0363481 100644
--- a/includes/specials/SpecialUndelete.php
+++ b/includes/specials/SpecialUndelete.php
@@ -32,7 +32,16 @@ class PageArchive {
* @var Title
*/
protected $title;
- var $fileStatus;
+
+ /**
+ * @var Status
+ */
+ protected $fileStatus;
+
+ /**
+ * @var Status
+ */
+ protected $revisionStatus;
function __construct( $title ) {
if( is_null( $title ) ) {
@@ -58,7 +67,7 @@ class PageArchive {
* given title prefix.
* Returns result wrapper with (ar_namespace, ar_title, count) fields.
*
- * @param $prefix String: title prefix
+ * @param string $prefix title prefix
* @return ResultWrapper
*/
public static function listPagesByPrefix( $prefix ) {
@@ -112,14 +121,24 @@ class PageArchive {
* @return ResultWrapper
*/
function listRevisions() {
+ global $wgContentHandlerUseDB;
+
$dbr = wfGetDB( DB_SLAVE );
+
+ $fields = array(
+ 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
+ 'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1',
+ );
+
+ if ( $wgContentHandlerUseDB ) {
+ $fields[] = 'ar_content_format';
+ $fields[] = 'ar_content_model';
+ }
+
$res = $dbr->select( 'archive',
- array(
- 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text',
- 'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1'
- ),
+ $fields,
array( 'ar_namespace' => $this->title->getNamespace(),
- 'ar_title' => $this->title->getDBkey() ),
+ 'ar_title' => $this->title->getDBkey() ),
__METHOD__,
array( 'ORDER BY' => 'ar_timestamp DESC' ) );
$ret = $dbr->resultObject( $res );
@@ -137,26 +156,9 @@ class PageArchive {
function listFiles() {
if( $this->title->getNamespace() == NS_FILE ) {
$dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( 'filearchive',
- array(
- 'fa_id',
- 'fa_name',
- 'fa_archive_name',
- 'fa_storage_key',
- 'fa_storage_group',
- 'fa_size',
- 'fa_width',
- 'fa_height',
- 'fa_bits',
- 'fa_metadata',
- 'fa_media_type',
- 'fa_major_mime',
- 'fa_minor_mime',
- 'fa_description',
- 'fa_user',
- 'fa_user_text',
- 'fa_timestamp',
- 'fa_deleted' ),
+ $res = $dbr->select(
+ 'filearchive',
+ ArchivedFile::selectFields(),
array( 'fa_name' => $this->title->getDBkey() ),
__METHOD__,
array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -174,28 +176,38 @@ class PageArchive {
* @return Revision
*/
function getRevision( $timestamp ) {
+ global $wgContentHandlerUseDB;
+
$dbr = wfGetDB( DB_SLAVE );
+
+ $fields = array(
+ 'ar_rev_id',
+ 'ar_text',
+ 'ar_comment',
+ 'ar_user',
+ 'ar_user_text',
+ 'ar_timestamp',
+ 'ar_minor_edit',
+ 'ar_flags',
+ 'ar_text_id',
+ 'ar_deleted',
+ 'ar_len',
+ 'ar_sha1',
+ );
+
+ if ( $wgContentHandlerUseDB ) {
+ $fields[] = 'ar_content_format';
+ $fields[] = 'ar_content_model';
+ }
+
$row = $dbr->selectRow( 'archive',
- array(
- 'ar_rev_id',
- 'ar_text',
- 'ar_comment',
- 'ar_user',
- 'ar_user_text',
- 'ar_timestamp',
- 'ar_minor_edit',
- 'ar_flags',
- 'ar_text_id',
- 'ar_deleted',
- 'ar_len',
- 'ar_sha1',
- ),
+ $fields,
array( 'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey(),
'ar_timestamp' => $dbr->timestamp( $timestamp ) ),
__METHOD__ );
if( $row ) {
- return Revision::newFromArchiveRow( $row, array( 'page' => $this->title->getArticleID() ) );
+ return Revision::newFromArchiveRow( $row, array( 'title' => $this->title ) );
} else {
return null;
}
@@ -218,9 +230,9 @@ class PageArchive {
$row = $dbr->selectRow( 'archive',
'ar_timestamp',
array( 'ar_namespace' => $this->title->getNamespace(),
- 'ar_title' => $this->title->getDBkey(),
- 'ar_timestamp < ' .
- $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
+ 'ar_title' => $this->title->getDBkey(),
+ 'ar_timestamp < ' .
+ $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
__METHOD__,
array(
'ORDER BY' => 'ar_timestamp DESC',
@@ -289,7 +301,7 @@ class PageArchive {
$row = $dbr->selectRow( 'archive',
array( 'ar_text', 'ar_flags', 'ar_text_id' ),
array( 'ar_namespace' => $this->title->getNamespace(),
- 'ar_title' => $this->title->getDBkey() ),
+ 'ar_title' => $this->title->getDBkey() ),
__METHOD__,
array( 'ORDER BY' => 'ar_timestamp DESC' ) );
if( $row ) {
@@ -308,7 +320,7 @@ class PageArchive {
$dbr = wfGetDB( DB_SLAVE );
$n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
array( 'ar_namespace' => $this->title->getNamespace(),
- 'ar_title' => $this->title->getDBkey() ),
+ 'ar_title' => $this->title->getDBkey() ),
__METHOD__
);
return ( $n > 0 );
@@ -319,7 +331,7 @@ class PageArchive {
* Once restored, the items will be removed from the archive tables.
* The deletion log will be updated with an undeletion notice.
*
- * @param $timestamps Array: pass an empty array to restore all revisions, otherwise list the ones to undelete.
+ * @param array $timestamps pass an empty array to restore all revisions, otherwise list the ones to undelete.
* @param $comment String
* @param $fileVersions Array
* @param $unsuppress Boolean
@@ -329,8 +341,6 @@ class PageArchive {
* on success, false on failure
*/
function undelete( $timestamps, $comment = '', $fileVersions = array(), $unsuppress = false, User $user = null ) {
- global $wgUser;
-
// If both the set of text revisions and file revisions are empty,
// restore everything. Otherwise, just restore the requested items.
$restoreAll = empty( $timestamps ) && empty( $fileVersions );
@@ -341,7 +351,7 @@ class PageArchive {
if( $restoreFiles && $this->title->getNamespace() == NS_FILE ) {
$img = wfLocalFile( $this->title );
$this->fileStatus = $img->restore( $fileVersions, $unsuppress );
- if ( !$this->fileStatus->isOk() ) {
+ if ( !$this->fileStatus->isOK() ) {
return false;
}
$filesRestored = $this->fileStatus->successCount;
@@ -350,10 +360,12 @@ class PageArchive {
}
if( $restoreText ) {
- $textRestored = $this->undeleteRevisions( $timestamps, $unsuppress, $comment );
- if( $textRestored === false ) { // It must be one of UNDELETE_*
+ $this->revisionStatus = $this->undeleteRevisions( $timestamps, $unsuppress, $comment );
+ if( !$this->revisionStatus->isOK() ) {
return false;
}
+
+ $textRestored = $this->revisionStatus->getValue();
} else {
$textRestored = 0;
}
@@ -379,6 +391,7 @@ class PageArchive {
}
if ( $user === null ) {
+ global $wgUser;
$user = $wgUser;
}
@@ -386,6 +399,9 @@ class PageArchive {
$logEntry->setPerformer( $user );
$logEntry->setTarget( $this->title );
$logEntry->setComment( $reason );
+
+ wfRunHooks( 'ArticleUndeleteLogEntry', array( $this, &$logEntry, $user ) );
+
$logid = $logEntry->insert();
$logEntry->publish( $logid );
@@ -397,15 +413,18 @@ class PageArchive {
* to the cur/old tables. If the page currently exists, all revisions will
* be stuffed into old, otherwise the most recent will go into cur.
*
- * @param $timestamps Array: pass an empty array to restore all revisions, otherwise list the ones to undelete.
- * @param $comment String
+ * @param array $timestamps pass an empty array to restore all revisions, otherwise list the ones to undelete.
* @param $unsuppress Boolean: remove all ar_deleted/fa_deleted restrictions of seletected revs
*
- * @return Mixed: number of revisions restored or false on failure
+ * @param $comment String
+ * @throws ReadOnlyError
+ * @return Status, containing the number of revisions restored on success
*/
private function undeleteRevisions( $timestamps, $unsuppress = false, $comment = '' ) {
+ global $wgContentHandlerUseDB;
+
if ( wfReadOnly() ) {
- return false;
+ throw new ReadOnlyError();
}
$restoreAll = empty( $timestamps );
@@ -420,7 +439,7 @@ class PageArchive {
$page = $dbw->selectRow( 'page',
array( 'page_id', 'page_latest' ),
array( 'page_namespace' => $this->title->getNamespace(),
- 'page_title' => $this->title->getDBkey() ),
+ 'page_title' => $this->title->getDBkey() ),
__METHOD__,
array( 'FOR UPDATE' ) // lock page
);
@@ -428,16 +447,21 @@ class PageArchive {
$makepage = false;
# Page already exists. Import the history, and if necessary
# we'll update the latest revision field in the record.
- $newid = 0;
- $pageId = $page->page_id;
- $previousRevId = $page->page_latest;
+
+ $previousRevId = $page->page_latest;
+
# Get the time span of this page
$previousTimestamp = $dbw->selectField( 'revision', 'rev_timestamp',
array( 'rev_id' => $previousRevId ),
__METHOD__ );
+
if( $previousTimestamp === false ) {
- wfDebug( __METHOD__.": existing page refers to a page_latest that does not exist\n" );
- return 0;
+ wfDebug( __METHOD__ . ": existing page refers to a page_latest that does not exist\n" );
+
+ $status = Status::newGood( 0 );
+ $status->warning( 'undeleterevision-missing' );
+
+ return $status;
}
} else {
# Have to create a new article...
@@ -457,24 +481,32 @@ class PageArchive {
$oldones = "ar_timestamp IN ( {$oldts} )";
}
+ $fields = array(
+ 'ar_rev_id',
+ 'ar_text',
+ 'ar_comment',
+ 'ar_user',
+ 'ar_user_text',
+ 'ar_timestamp',
+ 'ar_minor_edit',
+ 'ar_flags',
+ 'ar_text_id',
+ 'ar_deleted',
+ 'ar_page_id',
+ 'ar_len',
+ 'ar_sha1'
+ );
+
+ if ( $wgContentHandlerUseDB ) {
+ $fields[] = 'ar_content_format';
+ $fields[] = 'ar_content_model';
+ }
+
/**
* Select each archived revision...
*/
$result = $dbw->select( 'archive',
- /* fields */ array(
- 'ar_rev_id',
- 'ar_text',
- 'ar_comment',
- 'ar_user',
- 'ar_user_text',
- 'ar_timestamp',
- 'ar_minor_edit',
- 'ar_flags',
- 'ar_text_id',
- 'ar_deleted',
- 'ar_page_id',
- 'ar_len',
- 'ar_sha1' ),
+ $fields,
/* WHERE */ array(
'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey(),
@@ -486,29 +518,51 @@ class PageArchive {
$rev_count = $dbw->numRows( $result );
if( !$rev_count ) {
wfDebug( __METHOD__ . ": no revisions to restore\n" );
- return false; // ???
+
+ $status = Status::newGood( 0 );
+ $status->warning( "undelete-no-results" );
+ return $status;
}
$ret->seek( $rev_count - 1 ); // move to last
$row = $ret->fetchObject(); // get newest archived rev
$ret->seek( 0 ); // move back
+ // grab the content to check consistency with global state before restoring the page.
+ $revision = Revision::newFromArchiveRow( $row,
+ array(
+ 'title' => $article->getTitle(), // used to derive default content model
+ )
+ );
+ $user = User::newFromName( $revision->getRawUserText(), false );
+ $content = $revision->getContent( Revision::RAW );
+
+ //NOTE: article ID may not be known yet. prepareSave() should not modify the database.
+ $status = $content->prepareSave( $article, 0, -1, $user );
+
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+
if( $makepage ) {
// Check the state of the newest to-be version...
if( !$unsuppress && ( $row->ar_deleted & Revision::DELETED_TEXT ) ) {
- return false; // we can't leave the current revision like this!
+ return Status::newFatal( "undeleterevdel" );
}
// Safe to insert now...
- $newid = $article->insertOn( $dbw );
+ $newid = $article->insertOn( $dbw );
$pageId = $newid;
} else {
// Check if a deleted revision will become the current revision...
if( $row->ar_timestamp > $previousTimestamp ) {
// Check the state of the newest to-be version...
if( !$unsuppress && ( $row->ar_deleted & Revision::DELETED_TEXT ) ) {
- return false; // we can't leave the current revision like this!
+ return Status::newFatal( "undeleterevdel" );
}
}
+
+ $newid = false;
+ $pageId = $article->getId();
}
$revision = null;
@@ -528,6 +582,7 @@ class PageArchive {
$revision = Revision::newFromArchiveRow( $row,
array(
'page' => $pageId,
+ 'title' => $this->title,
'deleted' => $unsuppress ? 0 : $row->ar_deleted
) );
@@ -546,7 +601,7 @@ class PageArchive {
// Was anything restored at all?
if ( $restored == 0 ) {
- return 0;
+ return Status::newGood( 0 );
}
$created = (bool)$newid;
@@ -566,13 +621,18 @@ class PageArchive {
$update->doUpdate();
}
- return $restored;
+ return Status::newGood( $restored );
}
/**
* @return Status
*/
function getFileStatus() { return $this->fileStatus; }
+
+ /**
+ * @return Status
+ */
+ function getRevisionStatus() { return $this->revisionStatus; }
}
/**
@@ -721,7 +781,7 @@ class SpecialUndelete extends SpecialPage {
'action' => $wgScript ) ) .
Xml::fieldset( $this->msg( 'undelete-search-box' )->text() ) .
Html::hidden( 'title',
- $this->getTitle()->getPrefixedDbKey() ) .
+ $this->getTitle()->getPrefixedDBkey() ) .
Xml::inputLabel( $this->msg( 'undelete-search-prefix' )->text(),
'prefix', 'prefix', 20,
$this->mSearchPrefix ) . ' ' .
@@ -748,7 +808,7 @@ class SpecialUndelete extends SpecialPage {
if( $result->numRows() == 0 ) {
$out->addWikiMsg( 'undelete-no-results' );
- return;
+ return false;
}
$out->addWikiMsg( 'undeletepagetext', $this->getLanguage()->formatNum( $result->numRows() ) );
@@ -780,11 +840,13 @@ class SpecialUndelete extends SpecialPage {
private function showRevision( $timestamp ) {
if( !preg_match( '/[0-9]{14}/', $timestamp ) ) {
- return 0;
+ return;
}
$archive = new PageArchive( $this->mTargetObj );
- wfRunHooks( 'UndeleteForm::showRevision', array( &$archive, $this->mTargetObj ) );
+ if ( !wfRunHooks( 'UndeleteForm::showRevision', array( &$archive, $this->mTargetObj ) ) ) {
+ return;
+ }
$rev = $archive->getRevision( $timestamp );
$out = $this->getOutput();
@@ -834,7 +896,11 @@ class SpecialUndelete extends SpecialPage {
$t = $lang->userTime( $timestamp, $user );
$userLink = Linker::revUserTools( $rev );
- if( $this->mPreview ) {
+ $content = $rev->getContent( Revision::FOR_THIS_USER, $user );
+
+ $isText = ( $content instanceof TextContent );
+
+ if( $this->mPreview || $isText ) {
$openDiv = '<div id="mw-undelete-revision" class="mw-warning">';
} else {
$openDiv = '<div id="mw-undelete-revision">';
@@ -851,30 +917,55 @@ class SpecialUndelete extends SpecialPage {
$out->addHTML( $this->msg( 'undelete-revision' )->rawParams( $link )->params(
$time )->rawParams( $userLink )->params( $d, $t )->parse() . '</div>' );
- wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) );
- if( $this->mPreview ) {
+ if ( !wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) ) ) {
+ return;
+ }
+
+ if( $this->mPreview || !$isText ) {
+ // NOTE: non-text content has no source view, so always use rendered preview
+
// Hide [edit]s
$popts = $out->parserOptions();
$popts->setEditSection( false );
- $out->parserOptions( $popts );
- $out->addWikiTextTitleTidy( $rev->getText( Revision::FOR_THIS_USER, $user ), $this->mTargetObj, true );
+
+ $pout = $content->getParserOutput( $this->mTargetObj, $rev->getId(), $popts, true );
+ $out->addParserOutput( $pout );
}
+ if ( $isText ) {
+ // source view for textual content
+ $sourceView = Xml::element( 'textarea', array(
+ 'readonly' => 'readonly',
+ 'cols' => $user->getIntOption( 'cols' ),
+ 'rows' => $user->getIntOption( 'rows' ) ),
+ $content->getNativeData() . "\n" );
+
+ $previewButton = Xml::element( 'input', array(
+ 'type' => 'submit',
+ 'name' => 'preview',
+ 'value' => $this->msg( 'showpreview' )->text() ) );
+ } else {
+ $sourceView = '';
+ $previewButton = '';
+ }
+
+ $diffButton = Xml::element( 'input', array(
+ 'name' => 'diff',
+ 'type' => 'submit',
+ 'value' => $this->msg( 'showdiff' )->text() ) );
+
$out->addHTML(
- Xml::element( 'textarea', array(
- 'readonly' => 'readonly',
- 'cols' => intval( $user->getOption( 'cols' ) ),
- 'rows' => intval( $user->getOption( 'rows' ) ) ),
- $rev->getText( Revision::FOR_THIS_USER, $user ) . "\n" ) .
- Xml::openElement( 'div' ) .
+ $sourceView .
+ Xml::openElement( 'div', array(
+ 'style' => 'clear: both' ) ) .
Xml::openElement( 'form', array(
'method' => 'post',
'action' => $this->getTitle()->getLocalURL( array( 'action' => 'submit' ) ) ) ) .
Xml::element( 'input', array(
'type' => 'hidden',
'name' => 'target',
- 'value' => $this->mTargetObj->getPrefixedDbKey() ) ) .
+ 'value' => $this->mTargetObj->getPrefixedDBkey() ) ) .
Xml::element( 'input', array(
'type' => 'hidden',
'name' => 'timestamp',
@@ -883,14 +974,8 @@ class SpecialUndelete extends SpecialPage {
'type' => 'hidden',
'name' => 'wpEditToken',
'value' => $user->getEditToken() ) ) .
- Xml::element( 'input', array(
- 'type' => 'submit',
- 'name' => 'preview',
- 'value' => $this->msg( 'showpreview' )->text() ) ) .
- Xml::element( 'input', array(
- 'name' => 'diff',
- 'type' => 'submit',
- 'value' => $this->msg( 'showdiff' )->text() ) ) .
+ $previewButton .
+ $diffButton .
Xml::closeElement( 'form' ) .
Xml::closeElement( 'div' ) );
}
@@ -904,26 +989,30 @@ class SpecialUndelete extends SpecialPage {
* @return String: HTML
*/
function showDiff( $previousRev, $currentRev ) {
- $diffEngine = new DifferenceEngine( $this->getContext() );
+ $diffContext = clone $this->getContext();
+ $diffContext->setTitle( $currentRev->getTitle() );
+ $diffContext->setWikiPage( WikiPage::factory( $currentRev->getTitle() ) );
+
+ $diffEngine = $currentRev->getContentHandler()->createDifferenceEngine( $diffContext );
$diffEngine->showDiffStyle();
$this->getOutput()->addHTML(
"<div>" .
- "<table width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
+ "<table style='width: 98%;' cellpadding='0' cellspacing='4' class='diff'>" .
"<col class='diff-marker' />" .
"<col class='diff-content' />" .
"<col class='diff-marker' />" .
"<col class='diff-content' />" .
"<tr>" .
- "<td colspan='2' width='50%' style='text-align: center' class='diff-otitle'>" .
+ "<td colspan='2' style='width: 50%; text-align: center' class='diff-otitle'>" .
$this->diffHeader( $previousRev, 'o' ) .
"</td>\n" .
- "<td colspan='2' width='50%' style='text-align: center' class='diff-ntitle'>" .
+ "<td colspan='2' style='width: 50%; text-align: center' class='diff-ntitle'>" .
$this->diffHeader( $currentRev, 'n' ) .
"</td>\n" .
"</tr>" .
- $diffEngine->generateDiffBody(
- $previousRev->getText( Revision::FOR_THIS_USER, $this->getUser() ),
- $currentRev->getText( Revision::FOR_THIS_USER, $this->getUser() ) ) .
+ $diffEngine->generateContentDiffBody(
+ $previousRev->getContent( Revision::FOR_THIS_USER, $this->getUser() ),
+ $currentRev->getContent( Revision::FOR_THIS_USER, $this->getUser() ) ) .
"</table>" .
"</div>\n"
);
@@ -967,10 +1056,10 @@ class SpecialUndelete extends SpecialPage {
$targetQuery
) .
'</strong></div>' .
- '<div id="mw-diff-'.$prefix.'title2">' .
+ '<div id="mw-diff-' . $prefix . 'title2">' .
Linker::revUserTools( $rev ) . '<br />' .
'</div>' .
- '<div id="mw-diff-'.$prefix.'title3">' .
+ '<div id="mw-diff-' . $prefix . 'title3">' .
Linker::revComment( $rev ) . $rdel . '<br />' .
'</div>';
}
@@ -1122,7 +1211,7 @@ class SpecialUndelete extends SpecialPage {
Xml::label( $this->msg( 'undeletecomment' )->text(), 'wpComment' ) .
"</td>
<td class='mw-input'>" .
- Xml::input( 'wpComment', 50, $this->mComment, array( 'id' => 'wpComment' ) ) .
+ Xml::input( 'wpComment', 50, $this->mComment, array( 'id' => 'wpComment' ) ) .
"</td>
</tr>
<tr>
@@ -1169,7 +1258,7 @@ class SpecialUndelete extends SpecialPage {
if ( $this->mAllowed ) {
# Slip in the hidden controls here
- $misc = Html::hidden( 'target', $this->mTarget );
+ $misc = Html::hidden( 'target', $this->mTarget );
$misc .= Html::hidden( 'wpEditToken', $this->getUser()->getEditToken() );
$misc .= Xml::closeElement( 'form' );
$out->addHTML( $misc );
@@ -1180,7 +1269,10 @@ class SpecialUndelete extends SpecialPage {
private function formatRevisionRow( $row, $earliestLiveTime, $remaining ) {
$rev = Revision::newFromArchiveRow( $row,
- array( 'page' => $this->mTargetObj->getArticleID() ) );
+ array(
+ 'title' => $this->mTargetObj
+ ) );
+
$revTextSize = '';
$ts = wfTimestamp( TS_MW, $row->ar_timestamp );
// Build checkboxen...
@@ -1237,7 +1329,7 @@ class SpecialUndelete extends SpecialPage {
// Revision delete links
$revdlink = Linker::getRevDeleteLink( $user, $rev, $this->mTargetObj );
- $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink , $userLink, $revTextSize, $comment )->escaped();
+ $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink, $userLink, $revTextSize, $comment )->escaped();
return "<li>$revisionRow</li>";
}
@@ -1286,7 +1378,7 @@ class SpecialUndelete extends SpecialPage {
*
* @param $rev Revision
* @param $titleObj Title
- * @param $ts string Timestamp
+ * @param string $ts Timestamp
* @return string
*/
function getPageLink( $rev, $titleObj, $ts ) {
@@ -1317,8 +1409,8 @@ class SpecialUndelete extends SpecialPage {
*
* @param $file File
* @param $titleObj Title
- * @param $ts string A timestamp
- * @param $key String: a storage key
+ * @param string $ts A timestamp
+ * @param string $key a storage key
*
* @return String: HTML fragment
*/
@@ -1417,14 +1509,22 @@ class SpecialUndelete extends SpecialPage {
$out->addHTML( $this->msg( 'undeletedpage' )->rawParams( $link )->parse() );
} else {
$out->setPageTitle( $this->msg( 'undelete-error' ) );
- $out->addWikiMsg( 'cannotundelete' );
- $out->addWikiMsg( 'undeleterevdel' );
}
- // Show file deletion warnings and errors
+ // Show revision undeletion warnings and errors
+ $status = $archive->getRevisionStatus();
+ if( $status && !$status->isGood() ) {
+ $out->addWikiText( '<div class="error">' . $status->getWikiText( 'cannotundelete', 'cannotundelete' ) . '</div>' );
+ }
+
+ // Show file undeletion warnings and errors
$status = $archive->getFileStatus();
if( $status && !$status->isGood() ) {
$out->addWikiText( '<div class="error">' . $status->getWikiText( 'undelete-error-short', 'undelete-error-long' ) . '</div>' );
}
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
diff --git a/includes/specials/SpecialUnlockdb.php b/includes/specials/SpecialUnlockdb.php
index 2e772540..35141d80 100644
--- a/includes/specials/SpecialUnlockdb.php
+++ b/includes/specials/SpecialUnlockdb.php
@@ -84,4 +84,8 @@ class SpecialUnlockdb extends FormSpecialPage {
$out->addSubtitle( $this->msg( 'unlockdbsuccesssub' ) );
$out->addWikiMsg( 'unlockdbsuccesstext' );
}
+
+ protected function getGroupName() {
+ return 'wiki';
+ }
}
diff --git a/includes/specials/SpecialUnusedcategories.php b/includes/specials/SpecialUnusedcategories.php
index 1bd38e17..6b91dd39 100644
--- a/includes/specials/SpecialUnusedcategories.php
+++ b/includes/specials/SpecialUnusedcategories.php
@@ -26,7 +26,9 @@
*/
class UnusedCategoriesPage extends QueryPage {
- function isExpensive() { return true; }
+ function isExpensive() {
+ return true;
+ }
function __construct( $name = 'Unusedcategories' ) {
parent::__construct( $name );
@@ -62,4 +64,8 @@ class UnusedCategoriesPage extends QueryPage {
$title = Title::makeTitle( NS_CATEGORY, $result->title );
return Linker::link( $title, htmlspecialchars( $title->getText() ) );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUnusedimages.php b/includes/specials/SpecialUnusedimages.php
index cdab557e..69553282 100644
--- a/includes/specials/SpecialUnusedimages.php
+++ b/includes/specials/SpecialUnusedimages.php
@@ -80,4 +80,7 @@ class UnusedimagesPage extends ImageQueryPage {
return $this->msg( 'unusedimagestext' )->parseAsBlock();
}
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUnusedtemplates.php b/includes/specials/SpecialUnusedtemplates.php
index 06077d1f..493e936a 100644
--- a/includes/specials/SpecialUnusedtemplates.php
+++ b/includes/specials/SpecialUnusedtemplates.php
@@ -35,9 +35,17 @@ class UnusedtemplatesPage extends QueryPage {
parent::__construct( $name );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
- function sortDescending() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
+
+ function sortDescending() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -77,4 +85,8 @@ class UnusedtemplatesPage extends QueryPage {
function getPageHeader() {
return $this->msg( 'unusedtemplatestext' )->parseAsBlock();
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUnwatchedpages.php b/includes/specials/SpecialUnwatchedpages.php
index e5a79413..05ec6b02 100644
--- a/includes/specials/SpecialUnwatchedpages.php
+++ b/includes/specials/SpecialUnwatchedpages.php
@@ -35,8 +35,13 @@ class UnwatchedpagesPage extends QueryPage {
parent::__construct( $name, 'unwatchedpages' );
}
- function isExpensive() { return true; }
- function isSyndicated() { return false; }
+ function isExpensive() {
+ return true;
+ }
+
+ function isSyndicated() {
+ return false;
+ }
function getQueryInfo() {
return array (
@@ -54,7 +59,9 @@ class UnwatchedpagesPage extends QueryPage {
);
}
- function sortDescending() { return false; }
+ function sortDescending() {
+ return false;
+ }
function getOrderFields() {
return array( 'page_namespace', 'page_title' );
@@ -87,4 +94,8 @@ class UnwatchedpagesPage extends QueryPage {
return $this->getLanguage()->specialList( $plink, $wlink );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php
index 43ea345b..89c06b2a 100644
--- a/includes/specials/SpecialUpload.php
+++ b/includes/specials/SpecialUpload.php
@@ -39,7 +39,7 @@ class SpecialUpload extends SpecialPage {
}
/** Misc variables **/
- public $mRequest; // The WebRequest or FauxRequest this form is supposed to handle
+ public $mRequest; // The WebRequest or FauxRequest this form is supposed to handle
public $mSourceType;
/**
@@ -54,7 +54,7 @@ class SpecialUpload extends SpecialPage {
public $mUploadClicked;
/** User input variables from the "description" section **/
- public $mDesiredDestName; // The requested target file name
+ public $mDesiredDestName; // The requested target file name
public $mComment;
public $mLicense;
@@ -66,10 +66,10 @@ class SpecialUpload extends SpecialPage {
/** Hidden variables **/
public $mDestWarningAck;
- public $mForReUpload; // The user followed an "overwrite this file" link
- public $mCancelUpload; // The user clicked "Cancel and return to upload form" button
+ public $mForReUpload; // The user followed an "overwrite this file" link
+ public $mCancelUpload; // The user clicked "Cancel and return to upload form" button
public $mTokenOk;
- public $mUploadSuccessful = false; // Subclasses can use this to determine whether a file was uploaded
+ public $mUploadSuccessful = false; // Subclasses can use this to determine whether a file was uploaded
/** Text injection points for hooks not using HTMLForm **/
public $uploadFormTextTop;
@@ -82,32 +82,30 @@ class SpecialUpload extends SpecialPage {
*/
protected function loadRequest() {
$this->mRequest = $request = $this->getRequest();
- $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
- $this->mUpload = UploadBase::createFromRequest( $request );
- $this->mUploadClicked = $request->wasPosted()
+ $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
+ $this->mUpload = UploadBase::createFromRequest( $request );
+ $this->mUploadClicked = $request->wasPosted()
&& ( $request->getCheck( 'wpUpload' )
|| $request->getCheck( 'wpUploadIgnoreWarning' ) );
// Guess the desired name from the filename if not provided
- $this->mDesiredDestName = $request->getText( 'wpDestFile' );
+ $this->mDesiredDestName = $request->getText( 'wpDestFile' );
if( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
$this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
}
- $this->mComment = $request->getText( 'wpUploadDescription' );
- $this->mLicense = $request->getText( 'wpLicense' );
+ $this->mComment = $request->getText( 'wpUploadDescription' );
+ $this->mLicense = $request->getText( 'wpLicense' );
-
- $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
- $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
+ $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
+ $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
|| $request->getCheck( 'wpUploadIgnoreWarning' );
- $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
- $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
- $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
-
+ $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
+ $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
+ $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
- $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
- $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
- || $request->getCheck( 'wpReUpload' ); // b/w compat
+ $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
+ $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
+ || $request->getCheck( 'wpReUpload' ); // b/w compat
// If it was posted check for the token (no remote POST'ing with user credentials)
$token = $request->getVal( 'wpEditToken' );
@@ -209,8 +207,8 @@ class SpecialUpload extends SpecialPage {
/**
* Get an UploadForm instance with title and text properly set.
*
- * @param $message String: HTML string to add to the form
- * @param $sessionKey String: session key in case this is a stashed upload
+ * @param string $message HTML string to add to the form
+ * @param string $sessionKey session key in case this is a stashed upload
* @param $hideIgnoreWarning Boolean: whether to hide "ignore warning" check box
* @return UploadForm
*/
@@ -246,9 +244,9 @@ class SpecialUpload extends SpecialPage {
LogEventsList::showLogExtract( $delNotice, array( 'delete', 'move' ),
$desiredTitleObj,
'', array( 'lim' => 10,
- 'conds' => array( "log_action != 'revision'" ),
- 'showIfEmpty' => false,
- 'msgKey' => array( 'upload-recreate-warning' ) )
+ 'conds' => array( "log_action != 'revision'" ),
+ 'showIfEmpty' => false,
+ 'msgKey' => array( 'upload-recreate-warning' ) )
);
}
$form->addPreText( $delNotice );
@@ -300,7 +298,7 @@ class SpecialUpload extends SpecialPage {
* essentially means that UploadBase::VERIFICATION_ERROR and
* UploadBase::EMPTY_FILE should not be passed here.
*
- * @param $message String: HTML message to be passed to mainUploadForm
+ * @param string $message HTML message to be passed to mainUploadForm
*/
protected function showRecoverableUploadError( $message ) {
$sessionKey = $this->mUpload->stashSession();
@@ -312,12 +310,12 @@ class SpecialUpload extends SpecialPage {
$this->showUploadForm( $form );
}
/**
- * Stashes the upload, shows the main form, but adds an "continue anyway button".
+ * Stashes the upload, shows the main form, but adds a "continue anyway button".
* Also checks whether there are actually warnings to display.
*
* @param $warnings Array
* @return boolean true if warnings were displayed, false if there are no
- * warnings and the should continue processing like there was no warning
+ * warnings and it should continue processing
*/
protected function showUploadWarning( $warnings ) {
# If there are no warnings, or warnings we can ignore, return early.
@@ -336,6 +334,9 @@ class SpecialUpload extends SpecialPage {
$warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
. '<ul class="warning">';
foreach( $warnings as $warning => $args ) {
+ if( $warning == 'badfilename' ) {
+ $this->mDesiredDestName = Title::makeTitle( NS_FILE, $args )->getText();
+ }
if( $warning == 'exists' ) {
$msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
} elseif( $warning == 'duplicate' ) {
@@ -371,7 +372,7 @@ class SpecialUpload extends SpecialPage {
/**
* Show the upload form with error message, but do not stash the file.
*
- * @param $message string HTML string
+ * @param string $message HTML string
*/
protected function showUploadError( $message ) {
$message = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n" .
@@ -473,17 +474,17 @@ class SpecialUpload extends SpecialPage {
if ( $wgUseCopyrightUpload ) {
$licensetxt = '';
if ( $license != '' ) {
- $licensetxt = '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+ $licensetxt = '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
}
- $pageText = '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n" .
- '== ' . $msg[ 'filestatus' ] . " ==\n" . $copyStatus . "\n" .
+ $pageText = '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n" .
+ '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n" .
"$licensetxt" .
- '== ' . $msg[ 'filesource' ] . " ==\n" . $source;
+ '== ' . $msg['filesource'] . " ==\n" . $source;
} else {
if ( $license != '' ) {
- $filedesc = $comment == '' ? '' : '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n";
+ $filedesc = $comment == '' ? '' : '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n";
$pageText = $filedesc .
- '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+ '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
} else {
$pageText = $comment;
}
@@ -520,11 +521,11 @@ class SpecialUpload extends SpecialPage {
}
}
-
/**
* Provides output to the user for a result of UploadBase::verifyUpload
*
- * @param $details Array: result of UploadBase::verifyUpload
+ * @param array $details result of UploadBase::verifyUpload
+ * @throws MWException
*/
protected function processVerificationError( $details ) {
global $wgFileExtensions;
@@ -622,7 +623,7 @@ class SpecialUpload extends SpecialPage {
* Formats a result of UploadBase::getExistsWarning as HTML
* This check is static and can be done pre-upload via AJAX
*
- * @param $exists Array: the result of UploadBase::getExistsWarning
+ * @param array $exists the result of UploadBase::getExistsWarning
* @return String: empty string if there is no warning or an HTML fragment
*/
public static function getExistsWarning( $exists ) {
@@ -645,7 +646,7 @@ class SpecialUpload extends SpecialPage {
$exists['normalizedFile']->getTitle()->getPrefixedText() )->parse();
} elseif ( $exists['warning'] == 'thumb' ) {
// Swapped argument order compared with other messages for backwards compatibility
- $warning = wfMessage( 'fileexists-thumbnail-yes',
+ $warning = wfMessage( 'fileexists-thumbnail-yes',
$exists['thumbFile']->getTitle()->getPrefixedText(), $filename )->parse();
} elseif ( $exists['warning'] == 'thumb-name' ) {
// Image w/o '180px-' does not exists, but we do not like these filenames
@@ -675,7 +676,7 @@ class SpecialUpload extends SpecialPage {
/**
* Get a list of warnings
*
- * @param $filename String: local filename, e.g. 'file exists', 'non-descriptive filename'
+ * @param string $filename local filename, e.g. 'file exists', 'non-descriptive filename'
* @return Array: list of warning messages
*/
public static function ajaxGetExistsWarning( $filename ) {
@@ -716,6 +717,9 @@ class SpecialUpload extends SpecialPage {
$gallery->toHtml() . "</li>\n";
}
+ protected function getGroupName() {
+ return 'media';
+ }
}
/**
@@ -789,6 +793,8 @@ class UploadForm extends HTMLForm {
* @return Array: descriptor array
*/
protected function getSourceSection() {
+ global $wgCopyUploadsFromSpecialUpload;
+
if ( $this->mSessionKey ) {
return array(
'SessionKey' => array(
@@ -802,7 +808,9 @@ class UploadForm extends HTMLForm {
);
}
- $canUploadByUrl = UploadFromUrl::isEnabled() && UploadFromUrl::isAllowed( $this->getUser() );
+ $canUploadByUrl = UploadFromUrl::isEnabled()
+ && UploadFromUrl::isAllowed( $this->getUser() )
+ && $wgCopyUploadsFromSpecialUpload;
$radio = $canUploadByUrl;
$selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
@@ -946,7 +954,7 @@ class UploadForm extends HTMLForm {
? 'filereuploadsummary'
: 'fileuploadsummary',
'default' => $this->mComment,
- 'cols' => intval( $this->getUser()->getOption( 'cols' ) ),
+ 'cols' => $this->getUser()->getIntOption( 'cols' ),
'rows' => 8,
)
);
@@ -1077,7 +1085,6 @@ class UploadForm extends HTMLForm {
$out = $this->getOutput();
$out->addJsConfigVars( $scriptVars );
-
$out->addModules( array(
'mediawiki.action.edit', // For <charinsert> support
'mediawiki.legacy.upload', // Old form stuff...
@@ -1106,7 +1113,7 @@ class UploadSourceField extends HTMLTextField {
* @return string
*/
function getLabelHtml( $cellAttributes = array() ) {
- $id = "wpSourceType{$this->mParams['upload-type']}";
+ $id = $this->mParams['id'];
$label = Html::rawElement( 'label', array( 'for' => $id ), $this->mLabel );
if ( !empty( $this->mParams['radio'] ) ) {
@@ -1134,4 +1141,3 @@ class UploadSourceField extends HTMLTextField {
: 60;
}
}
-
diff --git a/includes/specials/SpecialUploadStash.php b/includes/specials/SpecialUploadStash.php
index 1a00d731..ddf0c6da 100644
--- a/includes/specials/SpecialUploadStash.php
+++ b/includes/specials/SpecialUploadStash.php
@@ -57,7 +57,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
/**
* Execute page -- can output a file directly or show a listing of them.
*
- * @param $subPage String: subpage, e.g. in http://example.com/wiki/Special:UploadStash/foo.jpg, the "foo.jpg" part
+ * @param string $subPage subpage, e.g. in http://example.com/wiki/Special:UploadStash/foo.jpg, the "foo.jpg" part
* @return Boolean: success
*/
public function execute( $subPage ) {
@@ -73,7 +73,8 @@ class SpecialUploadStash extends UnlistedSpecialPage {
* If file available in stash, cats it out to the client as a simple HTTP response.
* n.b. Most sanity checking done in UploadStashLocalFile, so this is straightforward.
*
- * @param $key String: the key of a particular requested file
+ * @param string $key the key of a particular requested file
+ * @throws HttpError
* @return bool
*/
public function showUpload( $key ) {
@@ -113,6 +114,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
* application the transform parameters
*
* @param string $key
+ * @throws UploadStashBadPathException
* @return array
*/
private function parseKey( $key ) {
@@ -164,10 +166,11 @@ class SpecialUploadStash extends UnlistedSpecialPage {
/**
* Scale a file (probably with a locally installed imagemagick, or similar) and output it to STDOUT.
- * @param $file: File object
- * @param $params: scaling parameters ( e.g. array( width => '50' ) );
- * @param $flags: scaling flags ( see File:: constants )
+ * @param $file File
+ * @param array $params Scaling parameters ( e.g. array( width => '50' ) );
+ * @param int $flags Scaling flags ( see File:: constants )
* @throws MWException
+ * @throws UploadStashFileNotFoundException
* @return boolean success
*/
private function outputLocallyScaledThumb( $file, $params, $flags ) {
@@ -189,7 +192,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
// now we should construct a File, so we can get mime and other such info in a standard way
// n.b. mimetype may be different from original (ogx original -> jpeg thumb)
- $thumbFile = new UnregisteredLocalFile( false,
+ $thumbFile = new UnregisteredLocalFile( false,
$this->stash->repo, $thumbnailImage->getStoragePath(), false );
if ( !$thumbFile ) {
throw new UploadStashFileNotFoundException( "couldn't create local file object for thumbnail" );
@@ -258,6 +261,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
* Side effect: writes HTTP response to STDOUT.
*
* @param $file File object with a local path (e.g. UnregisteredLocalFile, LocalFile. Oddly these don't share an ancestor!)
+ * @throws SpecialUploadStashTooLargeException
* @return bool
*/
private function outputLocalFile( File $file ) {
@@ -273,8 +277,9 @@ class SpecialUploadStash extends UnlistedSpecialPage {
/**
* Output HTTP response of raw content
* Side effect: writes HTTP response to STDOUT.
- * @param $content String content
- * @param $contentType String mime type
+ * @param string $content content
+ * @param string $contentType mime type
+ * @throws SpecialUploadStashTooLargeException
* @return bool
*/
private function outputContents( $content, $contentType ) {
@@ -291,8 +296,8 @@ class SpecialUploadStash extends UnlistedSpecialPage {
* Output headers for streaming
* XXX unsure about encoding as binary; if we received from HTTP perhaps we should use that encoding, concatted with semicolon to mimeType as it usually is.
* Side effect: preps PHP to write headers to STDOUT.
- * @param String $contentType : string suitable for content-type header
- * @param String $size: length in bytes
+ * @param string $contentType : string suitable for content-type header
+ * @param string $size: length in bytes
*/
private static function outputFileHeaders( $contentType, $size ) {
header( "Content-Type: $contentType", true );
@@ -322,14 +327,9 @@ class SpecialUploadStash extends UnlistedSpecialPage {
/**
* Default action when we don't have a subpage -- just show links to the uploads we have,
* Also show a button to clear stashed files
- * @param $status [optional] Status: the result of processRequest
* @return bool
*/
- private function showUploads( $status = null ) {
- if ( $status === null ) {
- $status = Status::newGood();
- }
-
+ private function showUploads() {
// sets the title, etc.
$this->setHeaders();
$this->outputHeader();
@@ -344,7 +344,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
'name' => 'clear',
)
), $this->getContext(), 'clearStashedUploads' );
- $form->setSubmitCallback( array( __CLASS__ , 'tryClearStashedUploads' ) );
+ $form->setSubmitCallback( array( __CLASS__, 'tryClearStashedUploads' ) );
$form->setTitle( $this->getTitle() );
$form->setSubmitTextMsg( 'uploadstash-clear' );
diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php
index 58da77da..eef66914 100644
--- a/includes/specials/SpecialUserlogin.php
+++ b/includes/specials/SpecialUserlogin.php
@@ -95,9 +95,9 @@ class LoginForm extends SpecialPage {
$this->mReason = $request->getText( 'wpReason' );
$this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
$this->mPosted = $request->wasPosted();
- $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
$this->mCreateaccountMail = $request->getCheck( 'wpCreateaccountMail' )
&& $wgEnableEmail;
+ $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' ) && !$this->mCreateaccountMail;
$this->mLoginattempt = $request->getCheck( 'wpLoginattempt' );
$this->mAction = $request->getVal( 'action' );
$this->mRemember = $request->getCheck( 'wpRemember' );
@@ -149,6 +149,23 @@ class LoginForm extends SpecialPage {
$this->load();
$this->setHeaders();
+ global $wgSecureLogin;
+ if (
+ $this->mType !== 'signup' &&
+ $wgSecureLogin &&
+ WebRequest::detectProtocol() !== 'https'
+ ) {
+ $title = $this->getFullTitle();
+ $query = array(
+ 'returnto' => $this->mReturnTo,
+ 'returntoquery' => $this->mReturnToQuery,
+ 'wpStickHTTPS' => $this->mStickHTTPS
+ );
+ $url = $title->getFullURL( $query, false, PROTO_HTTPS );
+ $this->getOutput()->redirect( $url );
+ return;
+ }
+
if ( $par == 'signup' ) { # Check for [[Special:Userlogin/signup]]
$this->mType = 'signup';
}
@@ -180,19 +197,22 @@ class LoginForm extends SpecialPage {
return;
}
- $u = $this->addNewaccountInternal();
-
- if ( $u == null ) {
+ $status = $this->addNewaccountInternal();
+ if( !$status->isGood() ) {
+ $error = $this->getOutput()->parse( $status->getWikiText() );
+ $this->mainLoginForm( $error );
return;
}
+ $u = $status->getValue();
+
// Wipe the initial password and mail a temporary one
$u->setPassword( null );
$u->saveSettings();
$result = $this->mailPasswordInternal( $u, false, 'createaccount-title', 'createaccount-text' );
wfRunHooks( 'AddNewAccount', array( $u, true ) );
- $u->addNewUserLogEntry( true, $this->mReason );
+ $u->addNewUserLogEntry( 'byemail', $this->mReason );
$out = $this->getOutput();
$out->setPageTitle( $this->msg( 'accmailtitle' ) );
@@ -210,18 +230,34 @@ class LoginForm extends SpecialPage {
* @return bool
*/
function addNewAccount() {
- global $wgUser, $wgEmailAuthentication, $wgLoginLanguageSelector;
+ global $wgContLang, $wgUser, $wgEmailAuthentication, $wgLoginLanguageSelector;
# Create the account and abort if there's a problem doing so
- $u = $this->addNewAccountInternal();
- if( $u == null ) {
+ $status = $this->addNewAccountInternal();
+ if( !$status->isGood() ) {
+ $error = $this->getOutput()->parse( $status->getWikiText() );
+ $this->mainLoginForm( $error );
return false;
}
- # If we showed up language selection links, and one was in use, be
- # smart (and sensible) and save that language as the user's preference
- if( $wgLoginLanguageSelector && $this->mLanguage ) {
- $u->setOption( 'language', $this->mLanguage );
+ $u = $status->getValue();
+
+ # Only save preferences if the user is not creating an account for someone else.
+ if ( $this->getUser()->isAnon() ) {
+ # If we showed up language selection links, and one was in use, be
+ # smart (and sensible) and save that language as the user's preference
+ if( $wgLoginLanguageSelector && $this->mLanguage ) {
+ $u->setOption( 'language', $this->mLanguage );
+ } else {
+
+ # Otherwise the user's language preference defaults to $wgContLang,
+ # but it may be better to set it to their preferred $wgContLang variant,
+ # based on browser preferences or URL parameters.
+ $u->setOption( 'language', $wgContLang->getPreferredVariant() );
+ }
+ if ( $wgContLang->hasVariants() ) {
+ $u->setOption( 'variant', $wgContLang->getPreferredVariant() );
+ }
}
$out = $this->getOutput();
@@ -250,7 +286,7 @@ class LoginForm extends SpecialPage {
// wrong.
$this->getContext()->setUser( $u );
wfRunHooks( 'AddNewAccount', array( $u, false ) );
- $u->addNewUserLogEntry();
+ $u->addNewUserLogEntry( 'create' );
if( $this->hasSessionCookie() ) {
$this->successfulCreation();
} else {
@@ -262,23 +298,24 @@ class LoginForm extends SpecialPage {
$out->addWikiMsg( 'accountcreatedtext', $u->getName() );
$out->addReturnTo( $this->getTitle() );
wfRunHooks( 'AddNewAccount', array( $u, false ) );
- $u->addNewUserLogEntry( false, $this->mReason );
+ $u->addNewUserLogEntry( 'create2', $this->mReason );
}
return true;
}
/**
+ * Make a new user account using the loaded data.
* @private
- * @return bool|User
+ * @throws PermissionsError|ReadOnlyError
+ * @return Status
*/
- function addNewAccountInternal() {
+ public function addNewAccountInternal() {
global $wgAuth, $wgMemc, $wgAccountCreationThrottle,
$wgMinimalPasswordLength, $wgEmailConfirmToEdit;
// If the user passes an invalid domain, something is fishy
if( !$wgAuth->validDomain( $this->mDomain ) ) {
- $this->mainLoginForm( $this->msg( 'wrongpassword' )->text() );
- return false;
+ return Status::newFatal( 'wrongpassword' );
}
// If we are not allowing users to login locally, we should be checking
@@ -287,10 +324,14 @@ class LoginForm extends SpecialPage {
// create a local account and login as any domain user). We only need
// to check this for domains that aren't local.
if( 'local' != $this->mDomain && $this->mDomain != '' ) {
- if( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mUsername )
- || !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) ) ) {
- $this->mainLoginForm( $this->msg( 'wrongpassword' )->text() );
- return false;
+ if(
+ !$wgAuth->canCreateAccounts() &&
+ (
+ !$wgAuth->userExists( $this->mUsername ) ||
+ !$wgAuth->authenticate( $this->mUsername, $this->mPassword )
+ )
+ ) {
+ return Status::newFatal( 'wrongpassword' );
}
}
@@ -301,28 +342,28 @@ class LoginForm extends SpecialPage {
# Request forgery checks.
if ( !self::getCreateaccountToken() ) {
self::setCreateaccountToken();
- $this->mainLoginForm( $this->msg( 'nocookiesfornew' )->parse() );
- return false;
+ return Status::newFatal( 'nocookiesfornew' );
}
# The user didn't pass a createaccount token
if ( !$this->mToken ) {
- $this->mainLoginForm( $this->msg( 'sessionfailure' )->text() );
- return false;
+ return Status::newFatal( 'sessionfailure' );
}
# Validate the createaccount token
if ( $this->mToken !== self::getCreateaccountToken() ) {
- $this->mainLoginForm( $this->msg( 'sessionfailure' )->text() );
- return false;
+ return Status::newFatal( 'sessionfailure' );
}
# Check permissions
$currentUser = $this->getUser();
+ $creationBlock = $currentUser->isBlockedFromCreateAccount();
if ( !$currentUser->isAllowed( 'createaccount' ) ) {
throw new PermissionsError( 'createaccount' );
- } elseif ( $currentUser->isBlockedFromCreateAccount() ) {
- $this->userBlockedMessage( $currentUser->isBlockedFromCreateAccount() );
+ } elseif ( $creationBlock instanceof Block ) {
+ // Throws an ErrorPageError.
+ $this->userBlockedMessage( $creationBlock );
+ // This should never be reached.
return false;
}
@@ -334,58 +375,45 @@ class LoginForm extends SpecialPage {
$ip = $this->getRequest()->getIP();
if ( $currentUser->isDnsBlacklisted( $ip, true /* check $wgProxyWhitelist */ ) ) {
- $this->mainLoginForm( $this->msg( 'sorbs_create_account_reason' )->text() . ' ' . $this->msg( 'parentheses', $ip )->escaped() );
- return false;
+ return Status::newFatal( 'sorbs_create_account_reason' );
}
# Now create a dummy user ($u) and check if it is valid
$name = trim( $this->mUsername );
$u = User::newFromName( $name, 'creatable' );
if ( !is_object( $u ) ) {
- $this->mainLoginForm( $this->msg( 'noname' )->text() );
- return false;
- }
-
- if ( 0 != $u->idForName() ) {
- $this->mainLoginForm( $this->msg( 'userexists' )->text() );
- return false;
+ return Status::newFatal( 'noname' );
+ } elseif ( 0 != $u->idForName() ) {
+ return Status::newFatal( 'userexists' );
}
- if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
- $this->mainLoginForm( $this->msg( 'badretype' )->text() );
- return false;
- }
+ if ( $this->mCreateaccountMail ) {
+ # do not force a password for account creation by email
+ # set invalid password, it will be replaced later by a random generated password
+ $this->mPassword = null;
+ } else {
+ if ( $this->mPassword !== $this->mRetype ) {
+ return Status::newFatal( 'badretype' );
+ }
- # check for minimal password length
- $valid = $u->getPasswordValidity( $this->mPassword );
- if ( $valid !== true ) {
- if ( !$this->mCreateaccountMail ) {
- if ( is_array( $valid ) ) {
- $message = array_shift( $valid );
- $params = $valid;
- } else {
- $message = $valid;
- $params = array( $wgMinimalPasswordLength );
+ # check for minimal password length
+ $valid = $u->getPasswordValidity( $this->mPassword );
+ if ( $valid !== true ) {
+ if ( !is_array( $valid ) ) {
+ $valid = array( $valid, $wgMinimalPasswordLength );
}
- $this->mainLoginForm( $this->msg( $message, $params )->text() );
- return false;
- } else {
- # do not force a password for account creation by email
- # set invalid password, it will be replaced later by a random generated password
- $this->mPassword = null;
+ return call_user_func_array( 'Status::newFatal', $valid );
}
}
# if you need a confirmed email address to edit, then obviously you
# need an email address.
- if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
- $this->mainLoginForm( $this->msg( 'noemailtitle' )->text() );
- return false;
+ if ( $wgEmailConfirmToEdit && strval( $this->mEmail ) === '' ) {
+ return Status::newFatal( 'noemailtitle' );
}
- if( !empty( $this->mEmail ) && !Sanitizer::validateEmail( $this->mEmail ) ) {
- $this->mainLoginForm( $this->msg( 'invalidemailaddress' )->text() );
- return false;
+ if ( strval( $this->mEmail ) !== '' && !Sanitizer::validateEmail( $this->mEmail ) ) {
+ return Status::newFatal( 'invalidemailaddress' );
}
# Set some additional data so the AbortNewAccount hook can be used for
@@ -397,8 +425,7 @@ class LoginForm extends SpecialPage {
if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) {
// Hook point to add extra creation throttles and blocks
wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" );
- $this->mainLoginForm( $abortError );
- return false;
+ return Status::newFatal( new RawMessage( $abortError ) );
}
// Hook point to check for exempt from account creation throttle
@@ -412,16 +439,14 @@ class LoginForm extends SpecialPage {
$wgMemc->set( $key, 0, 86400 );
}
if ( $value >= $wgAccountCreationThrottle ) {
- $this->throttleHit( $wgAccountCreationThrottle );
- return false;
+ return Status::newFatal( 'acct_creation_throttle_hit', $wgAccountCreationThrottle );
}
$wgMemc->incr( $key );
}
}
if( !$wgAuth->addUser( $u, $this->mPassword, $this->mEmail, $this->mRealName ) ) {
- $this->mainLoginForm( $this->msg( 'externaldberror' )->text() );
- return false;
+ return Status::newFatal( 'externaldberror' );
}
self::clearCreateaccountToken();
@@ -434,13 +459,16 @@ class LoginForm extends SpecialPage {
*
* @param $u User object.
* @param $autocreate boolean -- true if this is an autocreation via auth plugin
- * @return User object.
+ * @return Status object, with the User object in the value member on success
* @private
*/
function initUser( $u, $autocreate ) {
global $wgAuth;
- $u->addToDatabase();
+ $status = $u->addToDatabase();
+ if ( !$status->isOK() ) {
+ return $status;
+ }
if ( $wgAuth->allowPasswordChange() ) {
$u->setPassword( $this->mPassword );
@@ -464,10 +492,9 @@ class LoginForm extends SpecialPage {
$u->saveSettings();
# Update user count
- $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
- $ssUpdate->doUpdate();
+ DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 0, 0, 0, 1 ) );
- return $u;
+ return Status::newGood( $u );
}
/**
@@ -533,7 +560,7 @@ class LoginForm extends SpecialPage {
}
$isAutoCreated = false;
- if ( 0 == $u->getID() ) {
+ if ( $u->getID() == 0 ) {
$status = $this->attemptAutoCreate( $u );
if ( $status !== self::SUCCESS ) {
return $status;
@@ -543,8 +570,9 @@ class LoginForm extends SpecialPage {
} else {
global $wgExternalAuthType, $wgAutocreatePolicy;
if ( $wgExternalAuthType && $wgAutocreatePolicy != 'never'
- && is_object( $this->mExtUser )
- && $this->mExtUser->authenticate( $this->mPassword ) ) {
+ && is_object( $this->mExtUser )
+ && $this->mExtUser->authenticate( $this->mPassword )
+ ) {
# The external user and local user have the same name and
# password, so we assume they're the same.
$this->mExtUser->linkToLocal( $u->getID() );
@@ -588,7 +616,7 @@ class LoginForm extends SpecialPage {
// faces etc will probably just fail cleanly here.
$retval = self::RESET_PASS;
} else {
- $retval = ( $this->mPassword == '' ) ? self::EMPTY_PASS : self::WRONG_PASS;
+ $retval = ( $this->mPassword == '' ) ? self::EMPTY_PASS : self::WRONG_PASS;
}
} elseif ( $wgBlockDisablesLogin && $u->isBlocked() ) {
// If we've enabled it, make it so that a blocked user cannot login
@@ -620,7 +648,7 @@ class LoginForm extends SpecialPage {
/**
* Increment the login attempt throttle hit count for the (username,current IP)
* tuple unless the throttle was already reached.
- * @param $username string The user name
+ * @param string $username The user name
* @return Bool|Integer The integer hit count or True if it is already at the limit
*/
public static function incLoginThrottle( $username ) {
@@ -648,7 +676,7 @@ class LoginForm extends SpecialPage {
/**
* Clear the login attempt throttle hit count for the (username,current IP) tuple.
- * @param $username string The user name
+ * @param string $username The user name
* @return void
*/
public static function clearLoginThrottle( $username ) {
@@ -713,24 +741,36 @@ class LoginForm extends SpecialPage {
}
wfDebug( __METHOD__ . ": creating account\n" );
- $this->initUser( $user, true );
+ $status = $this->initUser( $user, true );
+
+ if ( !$status->isOK() ) {
+ $errors = $status->getErrorsByType( 'error' );
+ $this->mAbortLoginErrorMsg = $errors[0]['message'];
+ return self::ABORTED;
+ }
+
return self::SUCCESS;
}
function processLogin() {
- global $wgMemc, $wgLang;
+ global $wgMemc, $wgLang, $wgSecureLogin;
switch ( $this->authenticateUserData() ) {
case self::SUCCESS:
# We've verified now, update the real record
$user = $this->getUser();
- if( (bool)$this->mRemember != (bool)$user->getOption( 'rememberpassword' ) ) {
+ if( (bool)$this->mRemember != $user->getBoolOption( 'rememberpassword' ) ) {
$user->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
$user->saveSettings();
} else {
$user->invalidateCache();
}
- $user->setCookies();
+
+ if( $wgSecureLogin && !$this->mStickHTTPS ) {
+ $user->setCookies( null, false );
+ } else {
+ $user->setCookies();
+ }
self::clearLoginToken();
// Reset the throttle
@@ -803,8 +843,11 @@ class LoginForm extends SpecialPage {
}
}
+ /**
+ * @param $error string
+ */
function resetLoginForm( $error ) {
- $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $error ) );
+ $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $error ) );
$reset = new SpecialChangePassword();
$reset->setContext( $this->getContext() );
$reset->execute( null );
@@ -813,12 +856,12 @@ class LoginForm extends SpecialPage {
/**
* @param $u User object
* @param $throttle Boolean
- * @param $emailTitle String: message name of email title
- * @param $emailText String: message name of email text
+ * @param string $emailTitle message name of email title
+ * @param string $emailText message name of email text
* @return Status object
*/
function mailPasswordInternal( $u, $throttle = true, $emailTitle = 'passwordremindertitle', $emailText = 'passwordremindertext' ) {
- global $wgServer, $wgScript, $wgNewPasswordExpiry;
+ global $wgCanonicalServer, $wgScript, $wgNewPasswordExpiry;
if ( $u->getEmail() == '' ) {
return Status::newFatal( 'noemail', $u->getName() );
@@ -835,14 +878,13 @@ class LoginForm extends SpecialPage {
$u->setNewpassword( $np, $throttle );
$u->saveSettings();
$userLanguage = $u->getOption( 'language' );
- $m = $this->msg( $emailText, $ip, $u->getName(), $np, $wgServer . $wgScript,
+ $m = $this->msg( $emailText, $ip, $u->getName(), $np, '<' . $wgCanonicalServer . $wgScript . '>',
round( $wgNewPasswordExpiry / 86400 ) )->inLanguage( $userLanguage )->text();
$result = $u->sendMail( $this->msg( $emailTitle )->inLanguage( $userLanguage )->text(), $m );
return $result;
}
-
/**
* Run any hooks registered for logins, then HTTP redirect to
* $this->mReturnTo (or Main Page if that's undefined). Formerly we had a
@@ -860,7 +902,8 @@ class LoginForm extends SpecialPage {
wfRunHooks( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
if( $injected_html !== '' ) {
- $this->displaySuccessfulLogin( 'loginsuccess', $injected_html );
+ $this->displaySuccessfulAction( $this->msg( 'loginsuccesstitle' ),
+ 'loginsuccess', $injected_html );
} else {
$this->executeReturnTo( 'successredirect' );
}
@@ -876,7 +919,7 @@ class LoginForm extends SpecialPage {
# Run any hooks; display injected HTML
$currentUser = $this->getUser();
$injected_html = '';
- $welcome_creation_msg = 'welcomecreation';
+ $welcome_creation_msg = 'welcomecreation-msg';
wfRunHooks( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
@@ -887,18 +930,21 @@ class LoginForm extends SpecialPage {
*/
wfRunHooks( 'BeforeWelcomeCreation', array( &$welcome_creation_msg, &$injected_html ) );
- $this->displaySuccessfulLogin( $welcome_creation_msg, $injected_html );
+ $this->displaySuccessfulAction( $this->msg( 'welcomeuser', $this->getUser()->getName() ),
+ $welcome_creation_msg, $injected_html );
}
/**
- * Display a "login successful" page.
+ * Display an "successful action" page.
+ *
+ * @param string|Message $title page's title
* @param $msgname string
* @param $injected_html string
*/
- private function displaySuccessfulLogin( $msgname, $injected_html ) {
+ private function displaySuccessfulAction( $title, $msgname, $injected_html ) {
$out = $this->getOutput();
- $out->setPageTitle( $this->msg( 'loginsuccesstitle' ) );
- if( $msgname ){
+ $out->setPageTitle( $title );
+ if ( $msgname ) {
$out->addWikiMsg( $msgname, wfEscapeWikiText( $this->getUser()->getName() ) );
}
@@ -913,6 +959,7 @@ class LoginForm extends SpecialPage {
* User::isBlockedFromCreateAccount(), which gets this block, ignores the 'hardblock'
* setting on blocks (bug 13611).
* @param $block Block the block causing this error
+ * @throws ErrorPageError
*/
function userBlockedMessage( Block $block ) {
# Let's be nice about this, it's likely that this feature will be used
@@ -922,23 +969,15 @@ class LoginForm extends SpecialPage {
# haven't bothered to log out before trying to create an account to
# evade it, but we'll leave that to their guilty conscience to figure
# out.
-
- $out = $this->getOutput();
- $out->setPageTitle( $this->msg( 'cantcreateaccounttitle' ) );
-
- $block_reason = $block->mReason;
- if ( strval( $block_reason ) === '' ) {
- $block_reason = $this->msg( 'blockednoreason' )->text();
- }
-
- $out->addWikiMsg(
+ throw new ErrorPageError(
+ 'cantcreateaccounttitle',
'cantcreateaccount-text',
- $block->getTarget(),
- $block_reason,
- $block->getByName()
+ array(
+ $block->getTarget(),
+ $block->mReason ? $block->mReason : $this->msg( 'blockednoreason' )->text(),
+ $block->getByName()
+ )
);
-
- $this->executeReturnTo( 'error' );
}
/**
@@ -965,14 +1004,22 @@ class LoginForm extends SpecialPage {
$returnToTitle = Title::newMainPage();
}
+ if ( $wgSecureLogin && !$this->mStickHTTPS ) {
+ $options = array( 'http' );
+ $proto = PROTO_HTTP;
+ } elseif( $wgSecureLogin ) {
+ $options = array( 'https' );
+ $proto = PROTO_HTTPS;
+ } else {
+ $options = array();
+ $proto = PROTO_RELATIVE;
+ }
+
if ( $type == 'successredirect' ) {
- $redirectUrl = $returnToTitle->getFullURL( $returnToQuery );
- if( $wgSecureLogin && !$this->mStickHTTPS ) {
- $redirectUrl = preg_replace( '/^https:/', 'http:', $redirectUrl );
- }
+ $redirectUrl = $returnToTitle->getFullURL( $returnToQuery, false, $proto );
$this->getOutput()->redirect( $redirectUrl );
} else {
- $this->getOutput()->addReturnTo( $returnToTitle, $returnToQuery );
+ $this->getOutput()->addReturnTo( $returnToTitle, $returnToQuery, null, $options );
}
}
@@ -983,7 +1030,7 @@ class LoginForm extends SpecialPage {
global $wgEnableEmail, $wgEnableUserEmail;
global $wgHiddenPrefs, $wgLoginLanguageSelector;
global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration;
- global $wgSecureLogin, $wgPasswordResetRoutes;
+ global $wgSecureLogin, $wgSecureLoginDefaultHTTPS, $wgPasswordResetRoutes;
$titleObj = $this->getTitle();
$user = $this->getUser();
@@ -1003,7 +1050,8 @@ class LoginForm extends SpecialPage {
}
}
- if ( $this->mUsername == '' ) {
+ // Pre-fill username (if not creating an account, bug 44775).
+ if ( $this->mUsername == '' && $this->mType != 'signup' ) {
if ( $user->isLoggedIn() ) {
$this->mUsername = $user->getName();
} else {
@@ -1016,6 +1064,7 @@ class LoginForm extends SpecialPage {
$q = 'action=submitlogin&type=signup';
$linkq = 'type=login';
$linkmsg = 'gotaccount';
+ $this->getOutput()->addModules( 'mediawiki.special.userlogin.signup' );
} else {
$template = new UserloginTemplate();
$q = 'action=submitlogin&type=login';
@@ -1047,6 +1096,11 @@ class LoginForm extends SpecialPage {
$template->set( 'link', '' );
}
+ // Decide if we default stickHTTPS on
+ if ( $wgSecureLoginDefaultHTTPS && $this->mAction != 'submitlogin' && !$this->mLoginattempt ) {
+ $this->mStickHTTPS = true;
+ }
+
$resetLink = $this->mType == 'signup'
? null
: is_array( $wgPasswordResetRoutes ) && in_array( true, array_values( $wgPasswordResetRoutes ) );
@@ -1055,6 +1109,7 @@ class LoginForm extends SpecialPage {
$template->set( 'name', $this->mUsername );
$template->set( 'password', $this->mPassword );
$template->set( 'retype', $this->mRetype );
+ $template->set( 'createemailset', $this->mCreateaccountMail );
$template->set( 'email', $this->mEmail );
$template->set( 'realname', $this->mRealName );
$template->set( 'domain', $this->mDomain );
@@ -1213,15 +1268,21 @@ class LoginForm extends SpecialPage {
* Renew the user's session id, using strong entropy
*/
private function renewSessionId() {
- if ( wfCheckEntropy() ) {
+ global $wgSecureLogin, $wgCookieSecure;
+ if( $wgSecureLogin && !$this->mStickHTTPS ) {
+ $wgCookieSecure = false;
+ }
+
+ // If either we don't trust PHP's entropy, or if we need
+ // to change cookie settings when logging in because of
+ // wpStickHTTPS, then change the session ID manually.
+ $cookieParams = session_get_cookie_params();
+ if ( wfCheckEntropy() && $wgCookieSecure == $cookieParams['secure'] ) {
session_regenerate_id( false );
} else {
- //If we don't trust PHP's entropy, we have to replace the session manually
$tmp = $_SESSION;
- session_unset();
- session_write_close();
- session_id( MWCryptRand::generateHex( 32 ) );
- session_start();
+ session_destroy();
+ wfSetupSession( MWCryptRand::generateHex( 32 ) );
$_SESSION = $tmp;
}
}
@@ -1260,13 +1321,6 @@ class LoginForm extends SpecialPage {
}
/**
- * @private
- */
- function throttleHit( $limit ) {
- $this->mainLoginForm( $this->msg( 'acct_creation_throttle_hit' )->numParams( $limit )->parse() );
- }
-
- /**
* Produce a bar of links which allow the user to select another language
* during login/registration but retain "returnto"
*
@@ -1295,8 +1349,8 @@ class LoginForm extends SpecialPage {
* Create a language selector link for a particular language
* Links back to this page preserving type and returnto
*
- * @param $text Link text
- * @param $lang Language code
+ * @param string $text Link text
+ * @param string $lang Language code
* @return string
*/
function makeLanguageSelectorLink( $text, $lang ) {
@@ -1324,4 +1378,8 @@ class LoginForm extends SpecialPage {
$query
);
}
+
+ protected function getGroupName() {
+ return 'login';
+ }
}
diff --git a/includes/specials/SpecialUserlogout.php b/includes/specials/SpecialUserlogout.php
index ab2bf0ac..d957e875 100644
--- a/includes/specials/SpecialUserlogout.php
+++ b/includes/specials/SpecialUserlogout.php
@@ -49,8 +49,11 @@ class SpecialUserlogout extends UnlistedSpecialPage {
$oldName = $user->getName();
$user->logout();
+ $loginURL = SpecialPage::getTitleFor( 'Userlogin' )->getFullURL(
+ $this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
+
$out = $this->getOutput();
- $out->addWikiMsg( 'logouttext' );
+ $out->addWikiMsg( 'logouttext', $loginURL );
// Hook.
$injected_html = '';
@@ -59,4 +62,8 @@ class SpecialUserlogout extends UnlistedSpecialPage {
$out->returnToMain();
}
+
+ protected function getGroupName() {
+ return 'login';
+ }
}
diff --git a/includes/specials/SpecialUserrights.php b/includes/specials/SpecialUserrights.php
index 9f5a48a5..d4baae28 100644
--- a/includes/specials/SpecialUserrights.php
+++ b/includes/specials/SpecialUserrights.php
@@ -54,7 +54,7 @@ class UserrightsPage extends SpecialPage {
|| !empty( $available['remove'] )
|| ( ( $this->isself || !$checkIfSelf ) &&
( !empty( $available['add-self'] )
- || !empty( $available['remove-self'] ) ) );
+ || !empty( $available['remove-self'] ) ) );
}
/**
@@ -62,6 +62,7 @@ class UserrightsPage extends SpecialPage {
* Depending on the submit button used, call a form or a save function.
*
* @param $par Mixed: string if any subpage provided, else null
+ * @throws UserBlockedError|PermissionsError
*/
public function execute( $par ) {
// If the visitor doesn't have permissions to assign or remove
@@ -152,8 +153,8 @@ class UserrightsPage extends SpecialPage {
* Save user groups changes in the database.
* Data comes from the editUserGroupsForm() form function
*
- * @param $username String: username to apply changes to.
- * @param $reason String: reason for group change
+ * @param string $username username to apply changes to.
+ * @param string $reason reason for group change
* @return null
*/
function saveUserGroups( $username, $reason = '' ) {
@@ -188,9 +189,9 @@ class UserrightsPage extends SpecialPage {
* Save user groups changes in the database.
*
* @param $user User object
- * @param $add Array of groups to add
- * @param $remove Array of groups to remove
- * @param $reason String: reason for group change
+ * @param array $add of groups to add
+ * @param array $remove of groups to remove
+ * @param string $reason reason for group change
* @return Array: Tuple of added, then removed groups
*/
function doSaveUserGroups( $user, $add, $remove, $reason = '' ) {
@@ -239,26 +240,25 @@ class UserrightsPage extends SpecialPage {
return array( $add, $remove );
}
-
/**
* Add a rights log entry for an action.
*/
function addLogEntry( $user, $oldGroups, $newGroups, $reason ) {
- $log = new LogPage( 'rights' );
-
- $log->addEntry( 'rights',
- $user->getUserPage(),
- $reason,
- array(
- $this->makeGroupNameListForLog( $oldGroups ),
- $this->makeGroupNameListForLog( $newGroups )
- )
- );
+ $logEntry = new ManualLogEntry( 'rights', 'rights' );
+ $logEntry->setPerformer( $this->getUser() );
+ $logEntry->setTarget( $user->getUserPage() );
+ $logEntry->setComment( $reason );
+ $logEntry->setParameters( array(
+ '4::oldgroups' => $oldGroups,
+ '5::newgroups' => $newGroups,
+ ) );
+ $logid = $logEntry->insert();
+ $logEntry->publish( $logid );
}
/**
* Edit user groups membership
- * @param $username String: name of the user.
+ * @param string $username name of the user.
*/
function editUserGroupsForm( $username ) {
$status = $this->fetchUser( $username );
@@ -354,7 +354,16 @@ class UserrightsPage extends SpecialPage {
}
}
+ /**
+ * Make a list of group names to be stored as parameter for log entries
+ *
+ * @deprecated in 1.21; use LogFormatter instead.
+ * @param $ids array
+ * @return string
+ */
function makeGroupNameListForLog( $ids ) {
+ wfDeprecated( __METHOD__, '1.21' );
+
if( empty( $ids ) ) {
return '';
} else {
@@ -369,7 +378,7 @@ class UserrightsPage extends SpecialPage {
global $wgScript;
$this->getOutput()->addHTML(
Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'name' => 'uluser', 'id' => 'mw-userrights-form1' ) ) .
- Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
+ Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
Xml::fieldset( $this->msg( 'userrights-lookup-user' )->text() ) .
Xml::inputLabel( $this->msg( 'userrights-user-editname' )->text(), 'user', 'username', 30, str_replace( '_', ' ', $this->mTarget ) ) . ' ' .
Xml::submitButton( $this->msg( 'editusergroup' )->text() ) .
@@ -383,7 +392,7 @@ class UserrightsPage extends SpecialPage {
* form will be able to manipulate based on the current user's system
* permissions.
*
- * @param $groups Array: list of groups the given user is in
+ * @param array $groups list of groups the given user is in
* @return Array: Tuple of addable, then removable groups
*/
protected function splitGroups( $groups ) {
@@ -409,27 +418,41 @@ class UserrightsPage extends SpecialPage {
*/
protected function showEditUserGroupsForm( $user, $groups ) {
$list = array();
+ $membersList = array();
foreach( $groups as $group ) {
$list[] = self::buildGroupLink( $group );
+ $membersList[] = self::buildGroupMemberLink( $group );
}
- $autolist = array();
+ $autoList = array();
+ $autoMembersList = array();
if ( $user instanceof User ) {
foreach( Autopromote::getAutopromoteGroups( $user ) as $group ) {
- $autolist[] = self::buildGroupLink( $group );
+ $autoList[] = self::buildGroupLink( $group );
+ $autoMembersList[] = self::buildGroupMemberLink( $group );
}
}
+ $language = $this->getLanguage();
+ $displayedList = $this->msg( 'userrights-groupsmember-type',
+ $language->listToText( $list ),
+ $language->listToText( $membersList )
+ )->plain();
+ $displayedAutolist = $this->msg( 'userrights-groupsmember-type',
+ $language->listToText( $autoList ),
+ $language->listToText( $autoMembersList )
+ )->plain();
+
$grouplist = '';
$count = count( $list );
- if( $count > 0 ) {
+ if ( $count > 0 ) {
$grouplist = $this->msg( 'userrights-groupsmember', $count, $user->getName() )->parse();
- $grouplist = '<p>' . $grouplist . ' ' . $this->getLanguage()->listToText( $list ) . "</p>\n";
+ $grouplist = '<p>' . $grouplist . ' ' . $displayedList . "</p>\n";
}
- $count = count( $autolist );
- if( $count > 0 ) {
+ $count = count( $autoList );
+ if ( $count > 0 ) {
$autogrouplistintro = $this->msg( 'userrights-groupsmember-auto', $count, $user->getName() )->parse();
- $grouplist .= '<p>' . $autogrouplistintro . ' ' . $this->getLanguage()->listToText( $autolist ) . "</p>\n";
+ $grouplist .= '<p>' . $autogrouplistintro . ' ' . $displayedAutolist . "</p>\n";
}
$userToolLinks = Linker::userToolLinks(
@@ -479,10 +502,17 @@ class UserrightsPage extends SpecialPage {
* @return string
*/
private static function buildGroupLink( $group ) {
- static $cache = array();
- if( !isset( $cache[$group] ) )
- $cache[$group] = User::makeGroupLinkHtml( $group, htmlspecialchars( User::getGroupName( $group ) ) );
- return $cache[$group];
+ return User::makeGroupLinkHtml( $group, User::getGroupName( $group ) );
+ }
+
+ /**
+ * Format a link to a group member description page
+ *
+ * @param $group string
+ * @return string
+ */
+ private static function buildGroupMemberLink( $group ) {
+ return User::makeGroupLinkHtml( $group, User::getGroupMember( $group ) );
}
/**
@@ -497,7 +527,7 @@ class UserrightsPage extends SpecialPage {
* Adds a table with checkboxes where you can select what groups to add/remove
*
* @todo Just pass the username string?
- * @param $usergroups Array: groups the user belongs to
+ * @param array $usergroups groups the user belongs to
* @param $user User a user object
* @return string XHTML table element with checkboxes
*/
@@ -534,14 +564,14 @@ class UserrightsPage extends SpecialPage {
}
# Build the HTML table
- $ret .= Xml::openElement( 'table', array( 'class' => 'mw-userrights-groups' ) ) .
+ $ret .= Xml::openElement( 'table', array( 'class' => 'mw-userrights-groups' ) ) .
"<tr>\n";
foreach( $columns as $name => $column ) {
if( $column === array() )
continue;
$ret .= Xml::element( 'th', null, $this->msg( 'userrights-' . $name . '-col', count( $column ) )->text() );
}
- $ret.= "</tr>\n<tr>\n";
+ $ret .= "</tr>\n<tr>\n";
foreach( $columns as $column ) {
if( $column === array() )
continue;
@@ -581,7 +611,7 @@ class UserrightsPage extends SpecialPage {
}
/**
- * @param $group string: the name of the group to check
+ * @param string $group the name of the group to check
* @return bool Can we add the group?
*/
private function canAdd( $group ) {
@@ -592,7 +622,7 @@ class UserrightsPage extends SpecialPage {
/**
* Returns $this->getUser()->changeableGroups()
*
- * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) )
+ * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ), 'add-self' => array( addablegroups to self ), 'remove-self' => array( removable groups from self ) )
*/
function changeableGroups() {
return $this->getUser()->changeableGroups();
@@ -609,4 +639,8 @@ class UserrightsPage extends SpecialPage {
$output->addHTML( Xml::element( 'h2', null, $rightsLogPage->getName()->text() ) );
LogEventsList::showLogExtract( $output, 'rights', $user->getUserPage() );
}
+
+ protected function getGroupName() {
+ return 'users';
+ }
}
diff --git a/includes/specials/SpecialVersion.php b/includes/specials/SpecialVersion.php
index 4e5b6bf5..81d17817 100644
--- a/includes/specials/SpecialVersion.php
+++ b/includes/specials/SpecialVersion.php
@@ -40,7 +40,7 @@ class SpecialVersion extends SpecialPage {
'https://svn.wikimedia.org/svnroot/mediawiki' => 'https://svn.wikimedia.org/viewvc/mediawiki',
);
- public function __construct(){
+ public function __construct() {
parent::__construct( 'Version' );
}
@@ -48,29 +48,43 @@ class SpecialVersion extends SpecialPage {
* main()
*/
public function execute( $par ) {
- global $wgSpecialVersionShowHooks;
+ global $wgSpecialVersionShowHooks, $IP;
$this->setHeaders();
$this->outputHeader();
$out = $this->getOutput();
$out->allowClickjacking();
- $text =
- $this->getMediaWikiCredits() .
- $this->softwareInformation() .
- $this->getEntryPointInfo() .
- $this->getExtensionCredits();
- if ( $wgSpecialVersionShowHooks ) {
- $text .= $this->getWgHooks();
- }
+ if( $par !== 'Credits' ) {
+ $text =
+ $this->getMediaWikiCredits() .
+ $this->softwareInformation() .
+ $this->getEntryPointInfo() .
+ $this->getExtensionCredits();
+ if ( $wgSpecialVersionShowHooks ) {
+ $text .= $this->getWgHooks();
+ }
- $out->addWikiText( $text );
- $out->addHTML( $this->IPInfo() );
+ $out->addWikiText( $text );
+ $out->addHTML( $this->IPInfo() );
- if ( $this->getRequest()->getVal( 'easteregg' ) ) {
- if ( $this->showEasterEgg() ) {
- // TODO: put something interesting here
+ if ( $this->getRequest()->getVal( 'easteregg' ) ) {
+ if ( $this->showEasterEgg() ) {
+ // TODO: put something interesting here
+ }
}
+ } else {
+ // Credits sub page
+
+ // Header
+ $out->addHTML( wfMessage( 'version-credits-summary' )->parseAsBlock() );
+
+ $wikiText = file_get_contents( $IP . '/CREDITS' );
+
+ // Take everything from the first section onwards, to remove the (not localized) header
+ $wikiText = substr( $wikiText, strpos( $wikiText, '==' ) );
+
+ $out->addWikiText( $wikiText );
}
}
@@ -100,6 +114,12 @@ class SpecialVersion extends SpecialPage {
public static function getCopyrightAndAuthorList() {
global $wgLang;
+ if ( defined( 'MEDIAWIKI_INSTALL' ) ) {
+ $othersLink = '[http://www.mediawiki.org/wiki/Special:Version/Credits ' . wfMessage( 'version-poweredby-others' )->text() . ']';
+ } else {
+ $othersLink = '[[Special:Version/Credits|' . wfMessage( 'version-poweredby-others' )->text() . ']]';
+ }
+
$authorList = array(
'Magnus Manske', 'Brion Vibber', 'Lee Daniel Crocker',
'Tim Starling', 'Erik Möller', 'Gabriel Wicke', 'Ævar Arnfjörð Bjarmason',
@@ -108,10 +128,7 @@ class SpecialVersion extends SpecialPage {
'Alexandre Emsenhuber', 'Siebrand Mazeland', 'Chad Horohoe',
'Roan Kattouw', 'Trevor Parscal', 'Bryan Tong Minh', 'Sam Reed',
'Victor Vasiliev', 'Rotem Liss', 'Platonides', 'Antoine Musso',
- 'Timo Tijhof',
- '[{{SERVER}}{{SCRIPTPATH}}/CREDITS ' .
- wfMessage( 'version-poweredby-others' )->text() .
- ']'
+ 'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw', $othersLink
);
return wfMessage( 'version-poweredby-credits', date( 'Y' ),
@@ -131,14 +148,14 @@ class SpecialVersion extends SpecialPage {
// wikimarkup can be used.
$software = array();
$software['[https://www.mediawiki.org/ MediaWiki]'] = self::getVersionLinked();
- $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . php_sapi_name() . ")";
+ $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . PHP_SAPI . ")";
$software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
// Allow a hook to add/remove items.
wfRunHooks( 'SoftwareInfo', array( &$software ) );
$out = Xml::element( 'h2', array( 'id' => 'mw-version-software' ), wfMessage( 'version-software' )->text() ) .
- Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-software' ) ) .
+ Xml::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-software' ) ) .
"<tr>
<th>" . wfMessage( 'version-software-product' )->text() . "</th>
<th>" . wfMessage( 'version-software-version' )->text() . "</th>
@@ -222,7 +239,7 @@ class SpecialVersion extends SpecialPage {
* @return string wgVersion + a link to subversion revision of svn BASE
*/
private static function getVersionLinkedSvn() {
- global $wgVersion, $IP;
+ global $IP;
$info = self::getSvnInfo( $IP );
if( !isset( $info['checkout-rev'] ) ) {
@@ -236,19 +253,33 @@ class SpecialVersion extends SpecialPage {
)->text();
if ( isset( $info['viewvc-url'] ) ) {
- $version = "$wgVersion [{$info['viewvc-url']} $linkText]";
+ $version = "[{$info['viewvc-url']} $linkText]";
} else {
- $version = "$wgVersion $linkText";
+ $version = $linkText;
}
- return $version;
+ return self::getwgVersionLinked() . " $version";
+ }
+
+ /**
+ * @return string
+ */
+ private static function getwgVersionLinked() {
+ global $wgVersion;
+ $versionUrl = "";
+ if( wfRunHooks( 'SpecialVersionVersionUrl', array( $wgVersion, &$versionUrl ) ) ) {
+ $versionParts = array();
+ preg_match( "/^(\d+\.\d+)/", $wgVersion, $versionParts );
+ $versionUrl = "https://www.mediawiki.org/wiki/MediaWiki_{$versionParts[1]}";
+ }
+ return "[$versionUrl $wgVersion]";
}
/**
* @return bool|string wgVersion + HEAD sha1 stripped to the first 7 chars. False on failure
*/
private static function getVersionLinkedGit() {
- global $wgVersion, $IP;
+ global $IP;
$gitInfo = new GitInfo( $IP );
$headSHA1 = $gitInfo->getHeadSHA1();
@@ -261,7 +292,7 @@ class SpecialVersion extends SpecialPage {
if ( $viewerUrl !== false ) {
$shortSHA1 = "[$viewerUrl $shortSHA1]";
}
- return "$wgVersion $shortSHA1";
+ return self::getwgVersionLinked() . " $shortSHA1";
}
/**
@@ -562,9 +593,8 @@ class SpecialVersion extends SpecialPage {
* @return String: HTML fragment
*/
private function IPInfo() {
- $ip = str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
- return "<!-- visited from $ip -->\n" .
- "<span style='display:none'>visited from $ip</span>";
+ $ip = str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
+ return "<!-- visited from $ip -->\n<span style='display:none'>visited from $ip</span>";
}
/**
@@ -576,8 +606,10 @@ class SpecialVersion extends SpecialPage {
function listAuthors( $authors ) {
$list = array();
foreach( (array)$authors as $item ) {
- if( $item == '...' ) {
+ if ( $item == '...' ) {
$list[] = $this->msg( 'version-poweredby-others' )->text();
+ } elseif ( substr( $item, -5 ) == ' ...]' ) {
+ $list[] = substr( $item, 0, -4 ) . $this->msg( 'version-poweredby-others' )->text() . "]";
} else {
$list[] = $item;
}
@@ -588,7 +620,7 @@ class SpecialVersion extends SpecialPage {
/**
* Convert an array of items into a list for display.
*
- * @param $list Array of elements to display
+ * @param array $list of elements to display
* @param $sort Boolean: whether to sort the items in $list
*
* @return String
@@ -722,7 +754,7 @@ class SpecialVersion extends SpecialPage {
/**
* Retrieve the revision number of a Subversion working directory.
*
- * @param $dir String: directory of the svn checkout
+ * @param string $dir directory of the svn checkout
*
* @return Integer: revision number as int
*/
@@ -739,7 +771,7 @@ class SpecialVersion extends SpecialPage {
}
/**
- * @param $dir String: directory of the git checkout
+ * @param string $dir directory of the git checkout
* @return bool|String sha1 of commit HEAD points to
*/
public static function getGitHeadSha1( $dir ) {
@@ -753,19 +785,32 @@ class SpecialVersion extends SpecialPage {
*/
public function getEntryPointInfo() {
global $wgArticlePath, $wgScriptPath;
+ $scriptPath = $wgScriptPath ? $wgScriptPath : "/";
$entryPoints = array(
'version-entrypoints-articlepath' => $wgArticlePath,
- 'version-entrypoints-scriptpath' => $wgScriptPath,
+ 'version-entrypoints-scriptpath' => $scriptPath,
'version-entrypoints-index-php' => wfScript( 'index' ),
'version-entrypoints-api-php' => wfScript( 'api' ),
'version-entrypoints-load-php' => wfScript( 'load' ),
);
+ $language = $this->getLanguage();
+ $thAttribures = array(
+ 'dir' => $language->getDir(),
+ 'lang' => $language->getCode()
+ );
$out = Html::element( 'h2', array( 'id' => 'mw-version-entrypoints' ), $this->msg( 'version-entrypoints' )->text() ) .
- Html::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'mw-version-entrypoints-table' ) ) .
+ Html::openElement( 'table',
+ array(
+ 'class' => 'wikitable plainlinks',
+ 'id' => 'mw-version-entrypoints-table',
+ 'dir' => 'ltr',
+ 'lang' => 'en'
+ )
+ ) .
Html::openElement( 'tr' ) .
- Html::element( 'th', array(), $this->msg( 'version-entrypoints-header-entrypoint' )->text() ) .
- Html::element( 'th', array(), $this->msg( 'version-entrypoints-header-url' )->text() ) .
+ Html::element( 'th', $thAttribures, $this->msg( 'version-entrypoints-header-entrypoint' )->text() ) .
+ Html::element( 'th', $thAttribures, $this->msg( 'version-entrypoints-header-url' )->text() ) .
Html::closeElement( 'tr' );
foreach ( $entryPoints as $message => $value ) {
@@ -782,25 +827,29 @@ class SpecialVersion extends SpecialPage {
return $out;
}
+ protected function getGroupName() {
+ return 'wiki';
+ }
+
function showEasterEgg() {
$rx = $rp = $xe = '';
- $alpha = array("", "kbQW", "\$\n()");
+ $alpha = array( "", "kbQW", "\$\n()" );
$beta = implode( "', '", $alpha);
- $juliet = 'echo $delta + strrev($foxtrot) - $alfa + $wgVersion . base64_decode($bravo) * $charlie';
+ $juliet = 'echo $delta + strrev( $foxtrot ) - $alfa + $wgVersion . base64_decode( $bravo ) * $charlie';
for ( $i = 1; $i <= 4; $i++ ) {
$rx .= '([^j]*)J';
$rp .= "+(\\$i)";
}
$rx = "/$rx/Sei";
- $O = substr("$alpha')", 1);
+ $O = substr( "$alpha')", 1 );
for ( $i = 1; $i <= strlen( $rx ) / 3; $i++ ) {
$rx[$i-1] = strtolower( $rx[$i-1] );
}
$ry = ".*?(.((.)(.))).{1,3}(.)(.{1,$i})(\\4.\\3)(.).*";
$ry = "/$ry/Sei";
- $O = substr("$beta')", 1);
- preg_match_all('/(?<=\$)[[:alnum:]]*/',substr($juliet, 0, $i<<1), $charlie);
+ $O = substr( "$beta')", 1 );
+ preg_match_all( '/(?<=\$)[[:alnum:]]*/', substr( $juliet, 0, $i<<1 ), $charlie );
foreach( $charlie[0] as $bravo ) {
$$bravo =& $xe;
}
@@ -883,7 +932,7 @@ class SpecialVersion extends SpecialPage {
趤굄𞓅䶍澥𞜅쨯𞰅Ⱕ쵥䗌찭𞽇䓭䓭䐍è惨𐩍Э薎è擨₎𞗆
mowoxf=<<<moDzk=hgs8GbPbqrcbvagDdJkbe zk=zk>0kssss?zk-0k10000:zk kbe zk=DDzk<<3&0kssssJ|Dzk>>13JJ^3658 kbe zk=pueDzk&0kssJ.pueDzk>>8JJ?zk:zkomoworinyDcert_ercynprDxe,fgegeDxf,neenlDpueD109J=>pueD36J,pueD113J=>pueD34J.pueD92J. 0 .pueD34JJJ,fgegeDxv,neenlDpueD13J=>snyfr,pueD10J=>snyfrJJJJwo';
- $haystack = preg_replace($ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet);
+ $haystack = preg_replace( $ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet );
return preg_replace( $rx, $rp, $haystack );
}
}
diff --git a/includes/specials/SpecialWantedcategories.php b/includes/specials/SpecialWantedcategories.php
index 0b1fb251..0035bfab 100644
--- a/includes/specials/SpecialWantedcategories.php
+++ b/includes/specials/SpecialWantedcategories.php
@@ -72,4 +72,8 @@ class WantedCategoriesPage extends WantedQueryPage {
$nlinks = $this->msg( 'nmembers' )->numParams( $result->value )->escaped();
return $this->getLanguage()->specialList( $plink, $nlinks );
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialWantedfiles.php b/includes/specials/SpecialWantedfiles.php
index f52f7bb9..9a2d30a3 100644
--- a/includes/specials/SpecialWantedfiles.php
+++ b/includes/specials/SpecialWantedfiles.php
@@ -42,7 +42,7 @@ class WantedFilesPage extends WantedQueryPage {
$catMessage = $this->msg( 'broken-file-category' )
->title( Title::newFromText( "Wanted Files", NS_MAIN ) )
->inContentLanguage();
-
+
if ( !$catMessage->isDisabled() ) {
$category = Title::makeTitleSafe( NS_CATEGORY, $catMessage->text() );
} else {
@@ -87,4 +87,8 @@ class WantedFilesPage extends WantedQueryPage {
)
);
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialWantedpages.php b/includes/specials/SpecialWantedpages.php
index 7673305d..acec4ea4 100644
--- a/includes/specials/SpecialWantedpages.php
+++ b/includes/specials/SpecialWantedpages.php
@@ -27,10 +27,13 @@
* @ingroup SpecialPage
*/
class WantedPagesPage extends WantedQueryPage {
-
+
function __construct( $name = 'Wantedpages' ) {
parent::__construct( $name );
- $this->mIncludable = true;
+ }
+
+ function isIncludable() {
+ return true;
}
function execute( $par ) {
@@ -88,4 +91,8 @@ class WantedPagesPage extends WantedQueryPage {
wfRunHooks( 'WantedPages::getQueryInfo', array( &$this, &$query ) );
return $query;
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialWantedtemplates.php b/includes/specials/SpecialWantedtemplates.php
index f3e33698..f5539c18 100644
--- a/includes/specials/SpecialWantedtemplates.php
+++ b/includes/specials/SpecialWantedtemplates.php
@@ -52,4 +52,8 @@ class WantedTemplatesPage extends WantedQueryPage {
'page_title = tl_title' ) ) )
);
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}
diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php
index 5dfc1133..c7f122b8 100644
--- a/includes/specials/SpecialWatchlist.php
+++ b/includes/specials/SpecialWatchlist.php
@@ -26,7 +26,7 @@ class SpecialWatchlist extends SpecialPage {
/**
* Constructor
*/
- public function __construct( $page = 'Watchlist' ){
+ public function __construct( $page = 'Watchlist' ) {
parent::__construct( $page );
}
@@ -76,7 +76,7 @@ class SpecialWatchlist extends SpecialPage {
$mode = SpecialEditWatchlist::getMode( $request, $par );
if( $mode !== false ) {
# TODO: localise?
- switch( $mode ){
+ switch( $mode ) {
case SpecialEditWatchlist::EDIT_CLEAR:
$mode = 'clear';
break;
@@ -91,7 +91,9 @@ class SpecialWatchlist extends SpecialPage {
return;
}
- $nitems = $this->countItems();
+ $dbr = wfGetDB( DB_SLAVE, 'watchlist' );
+
+ $nitems = $this->countItems( $dbr );
if ( $nitems == 0 ) {
$output->addWikiMsg( 'nowatchlist' );
return;
@@ -106,37 +108,30 @@ class SpecialWatchlist extends SpecialPage {
/* bool */ 'hideLiu' => (int)$user->getBoolOption( 'watchlisthideliu' ),
/* bool */ 'hidePatrolled' => (int)$user->getBoolOption( 'watchlisthidepatrolled' ),
/* bool */ 'hideOwn' => (int)$user->getBoolOption( 'watchlisthideown' ),
- /* ? */ 'namespace' => 'all',
+ /* bool */ 'extended' => (int)$user->getBoolOption( 'extendwatchlist' ),
+ /* ? */ 'namespace' => '', //means all
/* ? */ 'invert' => false,
/* bool */ 'associated' => false,
);
$this->customFilters = array();
wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ) );
foreach( $this->customFilters as $key => $params ) {
- $defaults[$key] = $params['msg'];
+ $defaults[$key] = $params['default'];
}
# Extract variables from the request, falling back to user preferences or
# other default values if these don't exist
- $prefs['days'] = floatval( $user->getOption( 'watchlistdays' ) );
- $prefs['hideminor'] = $user->getBoolOption( 'watchlisthideminor' );
- $prefs['hidebots'] = $user->getBoolOption( 'watchlisthidebots' );
- $prefs['hideanons'] = $user->getBoolOption( 'watchlisthideanons' );
- $prefs['hideliu'] = $user->getBoolOption( 'watchlisthideliu' );
- $prefs['hideown' ] = $user->getBoolOption( 'watchlisthideown' );
- $prefs['hidepatrolled' ] = $user->getBoolOption( 'watchlisthidepatrolled' );
-
- # Get query variables
$values = array();
- $values['days'] = $request->getVal( 'days', $prefs['days'] );
- $values['hideMinor'] = (int)$request->getBool( 'hideMinor', $prefs['hideminor'] );
- $values['hideBots'] = (int)$request->getBool( 'hideBots' , $prefs['hidebots'] );
- $values['hideAnons'] = (int)$request->getBool( 'hideAnons', $prefs['hideanons'] );
- $values['hideLiu'] = (int)$request->getBool( 'hideLiu' , $prefs['hideliu'] );
- $values['hideOwn'] = (int)$request->getBool( 'hideOwn' , $prefs['hideown'] );
- $values['hidePatrolled'] = (int)$request->getBool( 'hidePatrolled', $prefs['hidepatrolled'] );
+ $values['days'] = $request->getVal( 'days', $defaults['days'] );
+ $values['hideMinor'] = (int)$request->getBool( 'hideMinor', $defaults['hideMinor'] );
+ $values['hideBots'] = (int)$request->getBool( 'hideBots', $defaults['hideBots'] );
+ $values['hideAnons'] = (int)$request->getBool( 'hideAnons', $defaults['hideAnons'] );
+ $values['hideLiu'] = (int)$request->getBool( 'hideLiu', $defaults['hideLiu'] );
+ $values['hideOwn'] = (int)$request->getBool( 'hideOwn', $defaults['hideOwn'] );
+ $values['hidePatrolled'] = (int)$request->getBool( 'hidePatrolled', $defaults['hidePatrolled'] );
+ $values['extended'] = (int)$request->getBool( 'extended', $defaults['extended'] );
foreach( $this->customFilters as $key => $params ) {
- $values[$key] = (int)$request->getBool( $key );
+ $values[$key] = (int)$request->getBool( $key, $defaults[$key] );
}
# Get namespace value, if supplied, and prepare a WHERE fragment
@@ -190,13 +185,11 @@ class SpecialWatchlist extends SpecialPage {
return;
}
- $dbr = wfGetDB( DB_SLAVE, 'watchlist' );
-
# Possible where conditions
$conds = array();
if( $values['days'] > 0 ) {
- $conds[] = "rc_timestamp > '".$dbr->timestamp( time() - intval( $values['days'] * 86400 ) )."'";
+ $conds[] = 'rc_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( time() - intval( $values['days'] * 86400 ) ) );
}
# If the watchlist is relatively short, it's simplest to zip
@@ -207,7 +200,6 @@ class SpecialWatchlist extends SpecialPage {
# Up estimate of watched items by 15% to compensate for talk pages...
-
# Toggles
if( $values['hideOwn'] ) {
$conds[] = 'rc_user != ' . $user->getId();
@@ -232,8 +224,8 @@ class SpecialWatchlist extends SpecialPage {
}
# Toggle watchlist content (all recent edits or just the latest)
- if( $user->getOption( 'extendwatchlist' ) ) {
- $limitWatchlist = intval( $user->getOption( 'wllimit' ) );
+ if( $values['extended'] ) {
+ $limitWatchlist = $user->getIntOption( 'wllimit' );
$usePage = false;
} else {
# Top log Ids for a page are not stored
@@ -249,10 +241,10 @@ class SpecialWatchlist extends SpecialPage {
}
# Create output form
- $form = Xml::fieldset( $this->msg( 'watchlist-options' )->text(), false, array( 'id' => 'mw-watchlist-options' ) );
+ $form = Xml::fieldset( $this->msg( 'watchlist-options' )->text(), false, array( 'id' => 'mw-watchlist-options' ) );
# Show watchlist header
- $form .= $this->msg( 'watchlist-details' )->numParams( $nitems )->parse();
+ $form .= $this->msg( 'watchlist-details' )->numParams( $nitems )->parse() . "\n";
if( $user->getOption( 'enotifwatchlistpages' ) && $wgEnotifWatchlist) {
$form .= $this->msg( 'wlheader-enotif' )->parseAsBlock() . "\n";
@@ -260,19 +252,19 @@ class SpecialWatchlist extends SpecialPage {
if( $wgShowUpdatedMarker ) {
$form .= Xml::openElement( 'form', array( 'method' => 'post',
'action' => $this->getTitle()->getLocalUrl(),
- 'id' => 'mw-watchlist-resetbutton' ) ) .
- $this->msg( 'wlheader-showupdated' )->parse() . ' ' .
- Xml::submitButton( $this->msg( 'enotif_reset' )->text(), array( 'name' => 'dummy' ) ) .
- Html::hidden( 'reset', 'all' );
+ 'id' => 'mw-watchlist-resetbutton' ) ) . "\n" .
+ $this->msg( 'wlheader-showupdated' )->parse() .
+ Xml::submitButton( $this->msg( 'enotif_reset' )->text(), array( 'name' => 'dummy' ) ) . "\n" .
+ Html::hidden( 'reset', 'all' ) . "\n";
foreach ( $nondefaults as $key => $value ) {
- $form .= Html::hidden( $key, $value );
+ $form .= Html::hidden( $key, $value ) . "\n";
}
- $form .= Xml::closeElement( 'form' );
+ $form .= Xml::closeElement( 'form' ) . "\n";
}
- $form .= '<hr />';
+ $form .= "<hr />\n";
$tables = array( 'recentchanges', 'watchlist' );
- $fields = array( $dbr->tableName( 'recentchanges' ) . '.*' );
+ $fields = RecentChange::selectFields();
$join_conds = array(
'watchlist' => array(
'INNER JOIN',
@@ -291,17 +283,17 @@ class SpecialWatchlist extends SpecialPage {
$options['LIMIT'] = $limitWatchlist;
}
- $rollbacker = $user->isAllowed('rollback');
+ $rollbacker = $user->isAllowed( 'rollback' );
if ( $usePage || $rollbacker ) {
$tables[] = 'page';
- $join_conds['page'] = array('LEFT JOIN','rc_cur_id=page_id');
+ $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
if ( $rollbacker ) {
$fields[] = 'page_latest';
}
}
ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
- wfRunHooks('SpecialWatchlistQuery', array(&$conds,&$tables,&$join_conds,&$fields) );
+ wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields, $values ) );
$res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds );
$numRows = $res->numRows();
@@ -313,10 +305,10 @@ class SpecialWatchlist extends SpecialPage {
if( $values['days'] > 0 ) {
$timestamp = wfTimestampNow();
$wlInfo = $this->msg( 'wlnote' )->numParams( $numRows, round( $values['days'] * 24 ) )->params(
- $lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user ) )->parse() . '<br />';
+ $lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user ) )->parse() . "<br />\n";
}
- $cutofflinks = "\n" . $this->cutoffLinks( $values['days'], $nondefaults ) . "<br />\n";
+ $cutofflinks = $this->cutoffLinks( $values['days'], $nondefaults ) . "<br />\n";
# Spit out some control panel links
$filters = array(
@@ -340,12 +332,17 @@ class SpecialWatchlist extends SpecialPage {
$links[] = $this->showHideLink( $nondefaults, $msg, $name, $values[$name] );
}
+ $hiddenFields = $nondefaults;
+ unset( $hiddenFields['namespace'] );
+ unset( $hiddenFields['invert'] );
+ unset( $hiddenFields['associated'] );
+
# Namespace filter and put the whole form together.
$form .= $wlInfo;
$form .= $cutofflinks;
- $form .= $lang->pipeList( $links );
- $form .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-form-namespaceselector' ) );
- $form .= '<hr /><p>';
+ $form .= $lang->pipeList( $links ) . "\n";
+ $form .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-form-namespaceselector' ) ) . "\n";
+ $form .= "<hr />\n<p>";
$form .= Html::namespaceSelector(
array(
'selected' => $nameSpace,
@@ -371,15 +368,12 @@ class SpecialWatchlist extends SpecialPage {
$associated,
array( 'title' => $this->msg( 'tooltip-namespace_association' )->text() )
) . '&#160;';
- $form .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . '</p>';
- $form .= Html::hidden( 'days', $values['days'] );
- foreach ( $filters as $key => $msg ) {
- if ( $values[$key] ) {
- $form .= Html::hidden( $key, 1 );
- }
+ $form .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "</p>\n";
+ foreach ( $hiddenFields as $key => $value ) {
+ $form .= Html::hidden( $key, $value ) . "\n";
}
- $form .= Xml::closeElement( 'form' );
- $form .= Xml::closeElement( 'fieldset' );
+ $form .= Xml::closeElement( 'form' ) . "\n";
+ $form .= Xml::closeElement( 'fieldset' ) . "\n";
$output->addHTML( $form );
# If there's nothing to show, stop here
@@ -432,7 +426,10 @@ class SpecialWatchlist extends SpecialPage {
$rc->numberofWatchingusers = 0;
}
- $s .= $list->recentChangesLine( $rc, $updated, $counter );
+ $changeLine = $list->recentChangesLine( $rc, $updated, $counter );
+ if ( $changeLine !== false ) {
+ $s .= $changeLine;
+ }
}
$s .= $list->endRecentChangesList();
@@ -494,11 +491,10 @@ class SpecialWatchlist extends SpecialPage {
/**
* Count the number of items on a user's watchlist
*
+ * @param $dbr A database connection
* @return Integer
*/
- protected function countItems() {
- $dbr = wfGetDB( DB_SLAVE, 'watchlist' );
-
+ protected function countItems( $dbr ) {
# Fetch the raw count
$res = $dbr->select( 'watchlist', array( 'count' => 'COUNT(*)' ),
array( 'wl_user' => $this->getUser()->getId() ), __METHOD__ );
@@ -507,4 +503,8 @@ class SpecialWatchlist extends SpecialPage {
return floor( $count / 2 );
}
+
+ protected function getGroupName() {
+ return 'changes';
+ }
}
diff --git a/includes/specials/SpecialWhatlinkshere.php b/includes/specials/SpecialWhatlinkshere.php
index f1356493..cb3e985c 100644
--- a/includes/specials/SpecialWhatlinkshere.php
+++ b/includes/specials/SpecialWhatlinkshere.php
@@ -69,7 +69,7 @@ class SpecialWhatLinksHere extends SpecialPage {
$opts->validateIntBounds( 'limit', 0, 5000 );
// Give precedence to subpage syntax
- if ( isset($par) ) {
+ if ( isset( $par ) ) {
$opts->setValue( 'target', $par );
}
@@ -94,9 +94,9 @@ class SpecialWhatLinksHere extends SpecialPage {
}
/**
- * @param $level int Recursion level
+ * @param int $level Recursion level
* @param $target Title Target title
- * @param $limit int Number of entries to display
+ * @param int $limit Number of entries to display
* @param $from Title Display from this article ID
* @param $back Title Display from this article ID at backwards scrolling
*/
@@ -137,7 +137,7 @@ class SpecialWhatLinksHere extends SpecialPage {
);
$namespace = $this->opts->getValue( 'namespace' );
- if ( is_int($namespace) ) {
+ if ( is_int( $namespace ) ) {
$plConds['page_namespace'] = $namespace;
$tlConds['page_namespace'] = $namespace;
$ilConds['page_namespace'] = $namespace;
@@ -187,7 +187,7 @@ class SpecialWhatLinksHere extends SpecialPage {
$joinConds);
}
- if( ( !$fetchlinks || !$dbr->numRows($plRes) ) && ( $hidetrans || !$dbr->numRows($tlRes) ) && ( $hideimages || !$dbr->numRows($ilRes) ) ) {
+ if( ( !$fetchlinks || !$plRes->numRows() ) && ( $hidetrans || !$tlRes->numRows() ) && ( $hideimages || !$ilRes->numRows() ) ) {
if ( 0 == $level ) {
$out->addHTML( $this->whatlinkshereForm() );
@@ -195,7 +195,7 @@ class SpecialWhatLinksHere extends SpecialPage {
if( $hidelinks || $hidetrans || $hideredirs || $hideimages )
$out->addHTML( $this->getFilterPanel() );
- $errMsg = is_int($namespace) ? 'nolinkshere-ns' : 'nolinkshere';
+ $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
$out->addWikiMsg( $errMsg, $this->target->getPrefixedText() );
}
return;
@@ -360,7 +360,7 @@ class SpecialWhatLinksHere extends SpecialPage {
$next = $this->msg( 'whatlinkshere-next' )->numParams( $currentLimit )->escaped();
$changed = $this->opts->getChangedValues();
- unset($changed['target']); // Already in the request title
+ unset( $changed['target'] ); // Already in the request title
if ( 0 != $prevId ) {
$overrides = array( 'from' => $this->opts->getValue( 'back' ) );
@@ -446,7 +446,7 @@ class SpecialWhatLinksHere extends SpecialPage {
$hide = $this->msg( 'hide' )->escaped();
$changed = $this->opts->getChangedValues();
- unset($changed['target']); // Already in the request title
+ unset( $changed['target'] ); // Already in the request title
$links = array();
$types = array( 'hidetrans', 'hidelinks', 'hideredirs' );
@@ -459,9 +459,13 @@ class SpecialWhatLinksHere extends SpecialPage {
$chosen = $this->opts->getValue( $type );
$msg = $chosen ? $show : $hide;
$overrides = array( $type => !$chosen );
- $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
+ $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
$this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
}
return Xml::fieldset( $this->msg( 'whatlinkshere-filters' )->text(), $this->getLanguage()->pipeList( $links ) );
}
+
+ protected function getGroupName() {
+ return 'pagetools';
+ }
}
diff --git a/includes/specials/SpecialWithoutinterwiki.php b/includes/specials/SpecialWithoutinterwiki.php
index 2988b04f..37237407 100644
--- a/includes/specials/SpecialWithoutinterwiki.php
+++ b/includes/specials/SpecialWithoutinterwiki.php
@@ -95,4 +95,8 @@ class WithoutInterwikiPage extends PageQueryPage {
}
return $query;
}
+
+ protected function getGroupName() {
+ return 'maintenance';
+ }
}