$opts->add( 'namespace', '', FormOptions::INTNULL );
$opts->add( 'invert', false );
+ $opts->add( 'associated', false );
$opts->add( 'categories', '' );
$opts->add( 'categories_any', false );
# Namespace filtering
if( $opts['namespace'] !== '' ) {
- if( !$opts['invert'] ) {
- $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 {
- $conds[] = 'rc_namespace != ' . $dbr->addQuotes( $opts['namespace'] );
+ # 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;
}
$defaults = $opts->getAllValues();
$nondefaults = $opts->getChangedValues();
- $opts->consumeValues( array( 'namespace', 'invert', 'tagfilter',
+ $opts->consumeValues( array( 'namespace', 'invert', 'associated', 'tagfilter',
'categories', 'categories_any' ) );
$panel = array();
/**
* Creates the choose namespace selection
*
+ * @todo Uses radio buttons (HASHAR)
* @param $opts FormOptions
* @return String
*/
$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" );
}
/**
--- /dev/null
+<?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),
+ );
+ }
+
+}
+
+