Bug 2429 allow selection of associated namespace in recent changes

Done by adding yet another checkbox in Special:RecentChanges. The feature
also support namespace inversion.  For example, if you have selected
the TALK namespace with inversion and associated namespace, you will
be shown any changes which is not NS_MAIN or NS_TALK.

Tests:

SpecialRecentchanges tests only this feature. I had to filter out
the rc_timestamp condition which might cause trouble if the test
suite is run on another day. A better solution remains to be implemented.
This commit is contained in:
Antoine Musso 2011-03-02 20:40:40 +00:00
parent 3730ef7358
commit 2a165ac219
5 changed files with 161 additions and 8 deletions

View file

@ -81,6 +81,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
safely enabled. A ZIP file reader was added which can scan a ZIP file for
potentially dangerous Java applets. This allows applets to be blocked
specifically, rather than all ZIP files being blocked.
* (bug 2429) Allow selection of associated namespace in recent changes
=== Bug fixes in 1.18 ===
* (bug 23119) WikiError class and subclasses are now marked as deprecated

View file

@ -55,6 +55,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
$opts->add( 'namespace', '', FormOptions::INTNULL );
$opts->add( 'invert', false );
$opts->add( 'associated', false );
$opts->add( 'categories', '' );
$opts->add( 'categories_any', false );
@ -284,13 +285,26 @@ class SpecialRecentChanges extends IncludableSpecialPage {
# Namespace filtering
if( $opts['namespace'] !== '' ) {
if( !$opts['invert'] ) {
$conds[] = 'rc_namespace = ' . $dbr->addQuotes( $opts['namespace'] );
} else {
$conds[] = 'rc_namespace != ' . $dbr->addQuotes( $opts['namespace'] );
}
}
$selectedNS = $dbr->addQuotes( $opts['namespace'] );
$operator = $opts['invert'] ? '!=' : '=';
$boolean = $opts['invert'] ? 'AND' : 'OR';
# namespace association (bug 2429)
if( !$opts['associated'] ) {
$condition = "rc_namespace $operator $selectedNS";
} else {
# Also add the associated namespace
$associatedNS = $dbr->addQuotes(
MWNamespace::getAssociated( $opts['namespace'] )
);
$condition = "(rc_namespace $operator $selectedNS "
. $boolean
. " rc_namespace $operator $associatedNS)";
}
$conds[] = $condition;
}
wfVarDump( $conds );
return $conds;
}
@ -463,7 +477,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
$defaults = $opts->getAllValues();
$nondefaults = $opts->getChangedValues();
$opts->consumeValues( array( 'namespace', 'invert', 'tagfilter',
$opts->consumeValues( array( 'namespace', 'invert', 'associated', 'tagfilter',
'categories', 'categories_any' ) );
$panel = array();
@ -555,6 +569,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
/**
* Creates the choose namespace selection
*
* @todo Uses radio buttons (HASHAR)
* @param $opts FormOptions
* @return String
*/
@ -562,7 +577,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
$nsSelect = Xml::namespaceSelector( $opts['namespace'], '' );
$nsLabel = Xml::label( wfMsg('namespace'), 'namespace' );
$invert = Xml::checkLabel( wfMsg('invert'), 'invert', 'nsinvert', $opts['invert'] );
return array( $nsLabel, "$nsSelect $invert" );
$associated = Xml::checkLabel( wfMsg('namespace_association'), 'associated', 'nsassociated', $opts['associated'] );
return array( $nsLabel, "$nsSelect $invert $associated" );
}
/**

View file

@ -2964,6 +2964,7 @@ $1',
# Namespace form on various pages
'namespace' => 'Namespace:',
'invert' => 'Invert selection',
'namespace_association' => 'Associated namespace',
'blanknamespace' => '(Main)',
# Contributions

View file

@ -1989,6 +1989,7 @@ $wgMessageStructure = array(
'nsform' => array(
'namespace',
'invert',
'namespace_association',
'blanknamespace',
),
'contributions' => array(

View file

@ -0,0 +1,134 @@
<?php
/**
* Test class for SpecialRecentchanges class
*
* Copyright © 2011, Ashar Voultoiz
*
* @author Ashar Voultoiz
*/
class SpecialRecentchangesTest extends MediaWikiTestCase {
/**
* @var SpecialRecentChanges
*/
protected $rc;
function setUp() {
}
/** helper to test SpecialRecentchanges::buildMainQueryConds() */
private function assertConditions( $expected, $requestOptions = null, $message = '' ) {
global $wgRequest;
$savedGlobal = $wgRequest;
# Initialize a WebRequest object ...
$wgRequest = new FauxRequest( $requestOptions );
# ... then setup the rc object (which use wgRequest internally)
$this->rc = new SpecialRecentChanges();
$formOptions = $this->rc->setup( null );
# Filter out rc_timestamp conditions which depends on the test runtime
# This condition is not needed as of march 2, 2011 -- hashar
# FIXME: find a way to generate the correct rc_timestamp
$queryConditions = array_filter(
$this->rc->buildMainQueryConds( $formOptions ),
'SpecialRecentchangesTest::filterOutRcTimestampCondition'
);
$this->assertEquals(
$expected,
$queryConditions,
$message
);
$wgRequest = $savedGlobal;
}
/** return false if condition begin with 'rc_timestamp ' */
private static function filterOutRcTimestampCondition( $var ) {
return (false === strpos( $var, 'rc_timestamp ' ));
}
public function testRcNsFilter() {
$this->assertConditions(
array( # expected
'rc_bot' => 0,
#0 => "rc_timestamp >= '20110223000000'",
1 => "rc_namespace = '0'",
),
array(
'namespace' => NS_MAIN,
),
"rc conditions with no options (aka default setting)"
);
}
public function testRcNsFilterInversion() {
$this->assertConditions(
array( # expected
#0 => "rc_timestamp >= '20110223000000'",
'rc_bot' => 0,
1 => sprintf( "rc_namespace != '%s'", NS_MAIN ),
),
array(
'namespace' => NS_MAIN,
'invert' => 1,
),
"rc conditions with namespace inverted"
);
}
/**
* @bug 2429
* @dataProvider provideNamespacesAssociations
*/
public function testRcNsFilterAssociation( $ns1, $ns2 ) {
$this->assertConditions(
array( # expected
#0 => "rc_timestamp >= '20110223000000'",
'rc_bot' => 0,
1 => sprintf( "(rc_namespace = '%s' OR rc_namespace = '%s')", $ns1, $ns2 ),
),
array(
'namespace' => $ns1,
'associated' => 1,
),
"rc conditions with namespace inverted"
);
}
/**
* @bug 2429
* @dataProvider provideNamespacesAssociations
*/
public function testRcNsFilterAssociationWithInversion( $ns1, $ns2 ) {
$this->assertConditions(
array( # expected
#0 => "rc_timestamp >= '20110223000000'",
'rc_bot' => 0,
1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ),
),
array(
'namespace' => $ns1,
'associated' => 1,
'invert' => 1,
),
"rc conditions with namespace inverted"
);
}
/**
* Provides associated namespaces to test recent changes
* namespaces association filtering.
*/
public function provideNamespacesAssociations() {
return array( # (NS => Associated_NS)
array( NS_MAIN, NS_TALK),
array( NS_TALK, NS_MAIN),
);
}
}