Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
FlaggedRevsApiHooks
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 2
240
0.00% covered (danger)
0.00%
0 / 1
 onAPIGetAllowedParams
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 onAPIQueryAfterExecute
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
182
1<?php
2// phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
3// phpcs:disable MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic
4
5use MediaWiki\Api\Hook\APIGetAllowedParamsHook;
6use MediaWiki\Api\Hook\APIQueryAfterExecuteHook;
7use MediaWiki\MediaWikiServices;
8
9class FlaggedRevsApiHooks implements
10    APIGetAllowedParamsHook,
11    APIQueryAfterExecuteHook
12{
13
14    /**
15     * @inheritDoc
16     */
17    public function onAPIGetAllowedParams( $module, &$params, $flags ) {
18        if ( !$module instanceof ApiQueryRevisions ) {
19            return;
20        }
21        $params['prop'][ApiBase::PARAM_TYPE][] = 'flagged';
22    }
23
24    /**
25     * @inheritDoc
26     */
27    public function onAPIQueryAfterExecute( $module ) {
28        if ( !$module instanceof ApiQueryRevisions ) {
29            return;
30        }
31        $params = $module->extractRequestParams( false );
32        if ( !in_array( 'flagged', $params['prop'] ?? [] ) ) {
33            return;
34        }
35        if ( !in_array( 'ids', $params['prop'] ) ) {
36            $module->dieWithError(
37                [ 'apierror-invalidparammix-mustusewith', 'rvprop=flagged', 'rvprop=ids' ], 'missingparam'
38            );
39        }
40        // Get all requested pageids/revids in a mapping:
41        // pageid => revid => array_index of the revision
42        // we will need this later to add data to the result array
43        $result = $module->getResult();
44        $data = (array)$result->getResultData( [ 'query', 'pages' ], [ 'Strip' => 'all' ] );
45        $pageids = [];
46        foreach ( $data as $pageid => $page ) {
47            if ( is_array( $page ) && array_key_exists( 'revisions', $page ) ) {
48                foreach ( $page['revisions'] as $index => $rev ) {
49                    if ( is_array( $rev ) && array_key_exists( 'revid', $rev ) ) {
50                        $pageids[$pageid][$rev['revid']] = $index;
51                    }
52                }
53            }
54        }
55        if ( $pageids === [] ) {
56            return;
57        }
58
59        // Construct SQL Query
60        $db = MediaWikiServices::getInstance()
61            ->getDBLoadBalancerFactory()
62            ->getReplicaDatabase( false, 'api' );
63
64        $qb = $db->newSelectQueryBuilder()
65            ->select( [
66                'fr_page_id',
67                'fr_rev_id',
68                'fr_timestamp',
69                'fr_tags',
70                'user_name'
71            ] )
72            ->from( 'flaggedrevs' )
73            ->join( 'user', null, 'fr_user=user_id' );
74
75        $where = [];
76        // Construct WHERE-clause to avoid multiplying the number of scanned rows
77        // as flaggedrevs table has composite primary key (fr_page_id,fr_rev_id)
78        foreach ( $pageids as $pageid => $revids ) {
79            $where[] = $db->makeList( [ 'fr_page_id' => $pageid,
80                'fr_rev_id' => array_keys( $revids ) ], LIST_AND );
81        }
82        $qb->where( $db->makeList( $where, LIST_OR ) );
83
84        $res = $qb->caller( __METHOD__ )->fetchResultSet();
85
86        // Add flagging data to result array
87        foreach ( $res as $row ) {
88            $index = $pageids[$row->fr_page_id][$row->fr_rev_id];
89            $tags = FlaggedRevision::expandRevisionTags( $row->fr_tags );
90            $data = [
91                'user'             => $row->user_name,
92                'timestamp'     => wfTimestamp( TS_ISO_8601, $row->fr_timestamp ),
93                'level'         => 0,
94                'level_text'     => 'stable',
95                'tags' => array_merge( FlaggedRevision::getDefaultTags(), $tags ),
96            ];
97            $result->addValue(
98                [ 'query', 'pages', $row->fr_page_id, 'revisions', $index ],
99                'flagged',
100                $data
101            );
102        }
103    }
104}