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:
parent
3730ef7358
commit
2a165ac219
5 changed files with 161 additions and 8 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2964,6 +2964,7 @@ $1',
|
|||
# Namespace form on various pages
|
||||
'namespace' => 'Namespace:',
|
||||
'invert' => 'Invert selection',
|
||||
'namespace_association' => 'Associated namespace',
|
||||
'blanknamespace' => '(Main)',
|
||||
|
||||
# Contributions
|
||||
|
|
|
|||
|
|
@ -1989,6 +1989,7 @@ $wgMessageStructure = array(
|
|||
'nsform' => array(
|
||||
'namespace',
|
||||
'invert',
|
||||
'namespace_association',
|
||||
'blanknamespace',
|
||||
),
|
||||
'contributions' => array(
|
||||
|
|
|
|||
134
tests/phpunit/includes/specials/SpecialRecentchanges.php
Normal file
134
tests/phpunit/includes/specials/SpecialRecentchanges.php
Normal 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),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in a new issue