Page MenuHomePhabricator

Allow searching global rename log by old username via API
Open, Needs TriagePublic

Description

Currently, it is possible to search the global rename log via Special:Log with a query such as this. That query (as of the 2018-05-02) returns a single result.

It is also currently possible to list the log events in the global rename log via the API, using a query such as this. However, it is not possible to filter the log by the old username via the API.

As an API user, I would like to be able to search the global rename log by old username using the API.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald TranscriptMay 2 2018, 8:26 PM
Vvjjkkii renamed this task from Allow searching global rename log by old username via API to krdaaaaaaa.Jul 1 2018, 1:12 AM
Vvjjkkii triaged this task as High priority.
Vvjjkkii updated the task description. (Show Details)
Vvjjkkii removed a subscriber: Aklapper.
CommunityTechBot renamed this task from krdaaaaaaa to Allow searching global rename log by old username via API.Jul 1 2018, 8:24 AM
CommunityTechBot updated the task description. (Show Details)
CommunityTechBot added a subscriber: Aklapper.
CommunityTechBot raised the priority of this task from High to Needs Triage.Jul 3 2018, 2:01 AM

@Anomie do you have suggestions on how this should be implemented? Ideally it would exist in core's list=logevents. We need something like the LogEventsListGetExtraInputs and SpecialLogAddLogSearchRelations hooks.

1997kB added a subscriber: 1997kB.Feb 13 2019, 4:21 AM

We probably can't generically make log_search access available for the same reasons T85756: Make (redacted) log_search table available on ToolLabs can't make log_search available on the WMCS replicas. So it'll probably have to be something with hooks to allow the specific use case.

The equivalent to the 'LogEventsListGetExtraInputs' hook is, roughly, 'APIGetAllowedParams'. The difference is that you have to add your extra field always, not only when a particular log type is being used, and of course use API parameter definition syntax rather than HTMLForm syntax. An implementation might look like

/**
 * @see ApiBase::getAllowedParams
 * @param ApiBase $module API module.
 * @param array &$params Params array. Add your new parameter here.
 * @param int $flags Zero or more flags like ApiBase::GET_VALUES_FOR_HELP.
 */
public static function onAPIGetAllowedParams( ApiBase $module, array &$params, $flags ) {
    if ( $module instanceof ApiQueryLogEvents ) {
        $params['gblrenameoldname'] = [
            ApiBase::PARAM_TYPE => 'string',
        ];
    }
}

And then you'd also need to define an i18n message named "apihelp-query+logevents-param-gblrenameoldname" (or use ApiBase::PARAM_HELP_MSG to specify a different i18n message). The i18n message should mention that it only works in combination with $1type=gblrename or an $1action that begins with gblrename/.

There's currently no hook that works like 'SpecialLogAddLogSearchRelations'. We can make it work similarly to that hook though. Before ApiQueryLogEvents.php line 126 set $type = null;, and in the else case at line 150 set $type = $params['type'];. Then somewhere below you could do something like this:

$qc = [];
// @todo if $type === 'suppress' do like SpecialLog::execute() does for an
// 'offender' parameter, with the below as 'elseif'.
if ( $type !== null ) {
    Hooks::run( 'ApiQueryLogEventsAddLogSearchRelations', [ $type, $params, &$qc ] );
}
if ( $qc ) {
    $this->addTables( 'log_search' );
    $this->addWhere( $qc );
    $this->addJoinConds( [ 'log_search' => [ 'JOIN', 'ls_log_id = log_id' ] ] );
}

The implementation of that might look like

/**
 * @param string $type Log type being queried.
 * @param array $params API module parameters.
 * @param array &$qc Set conditions for the log_search table here, if applicable.
 *   e.g. [ 'ls_field' => 'foo', 'ls_value' => 'bar' ]
 */
public static function onApiQueryLogEventsAddLogSearchRelations( $type, array $params, array &$qc ) {
    if ( $type === 'gblrename' ) {
        $oldname = trim( $params['gblrenameoldname'] );
        $canonicalOldname = User::getCanonicalName( $oldname );
        if ( $oldname !== '' ) {
            $qc = [ 'ls_field' => 'oldname', 'ls_value' => $canonicalOldname ];
        }
    }
}
Anomie moved this task from Unsorted to Needs Code on the MediaWiki-API board.Feb 13 2019, 5:15 PM