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