*/
use MediaWiki\Logger\LoggerFactory;
use Wikimedia\Rdbms\DBQueryTimeoutError;
-use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IResultWrapper;
use Wikimedia\Rdbms\FakeResultWrapper;
use Wikimedia\Rdbms\IDatabase;
// Same format as filterGroupDefinitions, but for a single group (reviewStatus)
// that is registered conditionally.
+ private $legacyReviewStatusFilterGroupDefinition;
+
+ // Single filter group registered conditionally
private $reviewStatusFilterGroupDefinition;
- // Single filter registered conditionally
+ // Single filter group registered conditionally
private $hideCategorizationFilterDefinition;
/**
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_user = 0';
+ $actorMigration = ActorMigration::newMigration();
+ $actorQuery = $actorMigration->getJoin( 'rc_user' );
+ $tables += $actorQuery['tables'];
+ $join_conds += $actorQuery['joins'];
+ $conds[] = $actorMigration->isAnon( $actorQuery['fields']['rc_user'] );
},
'isReplacedInStructuredUi' => true,
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_user != 0';
+ $actorMigration = ActorMigration::newMigration();
+ $actorQuery = $actorMigration->getJoin( 'rc_user' );
+ $tables += $actorQuery['tables'];
+ $join_conds += $actorQuery['joins'];
+ $conds[] = $actorMigration->isNotAnon( $actorQuery['fields']['rc_user'] );
},
'isReplacedInStructuredUi' => true,
]
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $user = $ctx->getUser();
- $conds[] = 'rc_user_text != ' . $dbr->addQuotes( $user->getName() );
+ $actorQuery = ActorMigration::newMigration()->getWhere( $dbr, 'rc_user', $ctx->getUser() );
+ $tables += $actorQuery['tables'];
+ $join_conds += $actorQuery['joins'];
+ $conds[] = 'NOT(' . $actorQuery['conds'] . ')';
},
'cssClassSuffix' => 'self',
'isRowApplicableCallable' => function ( $ctx, $rc ) {
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $user = $ctx->getUser();
- $conds[] = 'rc_user_text = ' . $dbr->addQuotes( $user->getName() );
+ $actorQuery = ActorMigration::newMigration()
+ ->getWhere( $dbr, 'rc_user', $ctx->getUser(), false );
+ $tables += $actorQuery['tables'];
+ $join_conds += $actorQuery['joins'];
+ $conds[] = $actorQuery['conds'];
},
'cssClassSuffix' => 'others',
'isRowApplicableCallable' => function ( $ctx, $rc ) {
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_bot = 0';
+ $conds['rc_bot'] = 0;
},
'cssClassSuffix' => 'bot',
'isRowApplicableCallable' => function ( $ctx, $rc ) {
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_bot = 1';
+ $conds['rc_bot'] = 1;
},
'cssClassSuffix' => 'human',
'isRowApplicableCallable' => function ( $ctx, $rc ) {
]
],
- // reviewStatus (conditional)
+ // significance (conditional)
[
'name' => 'significance',
];
- $this->reviewStatusFilterGroupDefinition = [
+ $this->legacyReviewStatusFilterGroupDefinition = [
[
- 'name' => 'reviewStatus',
+ 'name' => 'legacyReviewStatus',
'title' => 'rcfilters-filtergroup-reviewstatus',
'class' => ChangesListBooleanFilterGroup::class,
- 'priority' => -5,
'filters' => [
[
'name' => 'hidepatrolled',
- 'label' => 'rcfilters-filter-patrolled-label',
- 'description' => 'rcfilters-filter-patrolled-description',
// rcshowhidepatr-show, rcshowhidepatr-hide
// wlshowhidepatr
'showHideSuffix' => 'showhidepatr',
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_patrolled = 0';
- },
- 'cssClassSuffix' => 'patrolled',
- 'isRowApplicableCallable' => function ( $ctx, $rc ) {
- return $rc->getAttribute( 'rc_patrolled' );
+ $conds['rc_patrolled'] = RecentChange::PRC_UNPATROLLED;
},
+ 'isReplacedInStructuredUi' => true,
],
[
'name' => 'hideunpatrolled',
- 'label' => 'rcfilters-filter-unpatrolled-label',
- 'description' => 'rcfilters-filter-unpatrolled-description',
'default' => false,
'queryCallable' => function ( $specialClassName, $ctx, $dbr, &$tables, &$fields, &$conds,
&$query_options, &$join_conds
) {
- $conds[] = 'rc_patrolled = 1';
+ $conds[] = 'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED;
},
- 'cssClassSuffix' => 'unpatrolled',
+ 'isReplacedInStructuredUi' => true,
+ ],
+ ],
+ ]
+ ];
+
+ $this->reviewStatusFilterGroupDefinition = [
+ [
+ 'name' => 'reviewStatus',
+ 'title' => 'rcfilters-filtergroup-reviewstatus',
+ 'class' => ChangesListStringOptionsFilterGroup::class,
+ 'isFullCoverage' => true,
+ 'priority' => -5,
+ 'filters' => [
+ [
+ 'name' => 'unpatrolled',
+ 'label' => 'rcfilters-filter-reviewstatus-unpatrolled-label',
+ 'description' => 'rcfilters-filter-reviewstatus-unpatrolled-description',
+ 'cssClassSuffix' => 'reviewstatus-unpatrolled',
'isRowApplicableCallable' => function ( $ctx, $rc ) {
- return !$rc->getAttribute( 'rc_patrolled' );
+ return $rc->getAttribute( 'rc_patrolled' ) == RecentChange::PRC_UNPATROLLED;
+ },
+ ],
+ [
+ 'name' => 'manual',
+ 'label' => 'rcfilters-filter-reviewstatus-manual-label',
+ 'description' => 'rcfilters-filter-reviewstatus-manual-description',
+ 'cssClassSuffix' => 'reviewstatus-manual',
+ 'isRowApplicableCallable' => function ( $ctx, $rc ) {
+ return $rc->getAttribute( 'rc_patrolled' ) == RecentChange::PRC_PATROLLED;
+ },
+ ],
+ [
+ 'name' => 'auto',
+ 'label' => 'rcfilters-filter-reviewstatus-auto-label',
+ 'description' => 'rcfilters-filter-reviewstatus-auto-description',
+ 'cssClassSuffix' => 'reviewstatus-auto',
+ 'isRowApplicableCallable' => function ( $ctx, $rc ) {
+ return $rc->getAttribute( 'rc_patrolled' ) == RecentChange::PRC_AUTOPATROLLED;
},
],
],
+ 'default' => ChangesListStringOptionsFilterGroup::NONE,
+ 'queryCallable' => function ( $specialPageClassName, $ctx, $dbr,
+ &$tables, &$fields, &$conds, &$query_options, &$join_conds, $selected
+ ) {
+ if ( $selected === [] ) {
+ return;
+ }
+ $rcPatrolledValues = [
+ 'unpatrolled' => RecentChange::PRC_UNPATROLLED,
+ 'manual' => RecentChange::PRC_PATROLLED,
+ 'auto' => RecentChange::PRC_AUTOPATROLLED,
+ ];
+ // e.g. rc_patrolled IN (0, 2)
+ $conds['rc_patrolled'] = array_map( function ( $s ) use ( $rcPatrolledValues ) {
+ return $rcPatrolledValues[ $s ];
+ }, $selected );
+ }
]
];
/**
* Get the database result for this special page instance. Used by ApiFeedRecentChanges.
*
- * @return bool|ResultWrapper Result or false
+ * @return bool|IResultWrapper Result or false
*/
public function getRows() {
$opts = $this->getOptions();
// information to all users just because the user that saves the edit can
// patrol or is logged in)
if ( !$this->including() && $this->getUser()->useRCPatrol() ) {
+ $this->registerFiltersFromDefinitions( $this->legacyReviewStatusFilterGroupDefinition );
$this->registerFiltersFromDefinitions( $this->reviewStatusFilterGroupDefinition );
}
}
/**
- * Replace old options 'hideanons' or 'hideliu' with structured UI equivalent
+ * Replace old options with their structured UI equivalents
*
* @param FormOptions $opts
* @return bool True if the change was made
return false;
}
+ $changed = false;
+
// At this point 'hideanons' and 'hideliu' cannot be both true,
// because fixBackwardsCompatibilityOptions resets (at least) 'hideanons' in such case
if ( $opts[ 'hideanons' ] ) {
$opts->reset( 'hideanons' );
$opts[ 'userExpLevel' ] = 'registered';
- return true;
+ $changed = true;
}
if ( $opts[ 'hideliu' ] ) {
$opts->reset( 'hideliu' );
$opts[ 'userExpLevel' ] = 'unregistered';
- return true;
+ $changed = true;
}
- return false;
+ if ( $this->getFilterGroup( 'legacyReviewStatus' ) ) {
+ if ( $opts[ 'hidepatrolled' ] ) {
+ $opts->reset( 'hidepatrolled' );
+ $opts[ 'reviewStatus' ] = 'unpatrolled';
+ $changed = true;
+ }
+
+ if ( $opts[ 'hideunpatrolled' ] ) {
+ $opts->reset( 'hideunpatrolled' );
+ $opts[ 'reviewStatus' ] = implode(
+ ChangesListStringOptionsFilterGroup::SEPARATOR,
+ [ 'manual', 'auto' ]
+ );
+ $changed = true;
+ }
+ }
+
+ return $changed;
}
/**
* @param array $query_options Array of query options; see IDatabase::select $options
* @param array $join_conds Array of join conditions; see IDatabase::select $join_conds
* @param FormOptions $opts
- * @return bool|ResultWrapper Result or false
+ * @return bool|IResultWrapper Result or false
*/
protected function doMainQuery( $tables, $fields, $conds,
$query_options, $join_conds, FormOptions $opts
/**
* Send output to the OutputPage object, only called if not used feeds
*
- * @param ResultWrapper $rows Database rows
+ * @param IResultWrapper $rows Database rows
* @param FormOptions $opts
*/
public function webOutput( $rows, $opts ) {
/**
* Build and output the actual changes list.
*
- * @param ResultWrapper $rows Database rows
+ * @param IResultWrapper $rows Database rows
* @param FormOptions $opts
*/
abstract public function outputChangesList( $rows, $opts );
return;
}
+ $actorMigration = ActorMigration::newMigration();
+ $actorQuery = $actorMigration->getJoin( 'rc_user' );
+ $tables += $actorQuery['tables'];
+ $join_conds += $actorQuery['joins'];
+
// 'registered' but not 'unregistered', experience levels, if any, are included in 'registered'
if (
in_array( 'registered', $selectedExpLevels ) &&
!in_array( 'unregistered', $selectedExpLevels )
) {
- $conds[] = 'rc_user != 0';
+ $conds[] = $actorMigration->isNotAnon( $actorQuery['fields']['rc_user'] );
return;
}
if ( $selectedExpLevels === [ 'unregistered' ] ) {
- $conds[] = 'rc_user = 0';
+ $conds[] = $actorMigration->isAnon( $actorQuery['fields']['rc_user'] );
return;
}
$tables[] = 'user';
- $join_conds['user'] = [ 'LEFT JOIN', 'rc_user = user_id' ];
+ $join_conds['user'] = [ 'LEFT JOIN', $actorQuery['fields']['rc_user'] . ' = user_id' ];
if ( $now === 0 ) {
$now = time();
if ( in_array( 'unregistered', $selectedExpLevels ) ) {
$selectedExpLevels = array_diff( $selectedExpLevels, [ 'unregistered' ] );
- $conditions[] = 'rc_user = 0';
+ $conditions[] = $actorMigration->isAnon( $actorQuery['fields']['rc_user'] );
}
if ( $selectedExpLevels === [ 'newcomer' ] ) {
} elseif ( $selectedExpLevels === [ 'experienced', 'learner' ] ) {
$conditions[] = $aboveNewcomer;
} elseif ( $selectedExpLevels === [ 'experienced', 'learner', 'newcomer' ] ) {
- $conditions[] = 'rc_user != 0';
+ $conditions[] = $actorMigration->isNotAnon( $actorQuery['fields']['rc_user'] );
}
if ( count( $conditions ) > 1 ) {