Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 56 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
FlaggedRevsApiHooks | |
0.00% |
0 / 56 |
|
0.00% |
0 / 2 |
240 | |
0.00% |
0 / 1 |
onAPIGetAllowedParams | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
onAPIQueryAfterExecute | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
182 |
1 | <?php |
2 | // phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName |
3 | // phpcs:disable MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic |
4 | |
5 | use MediaWiki\Api\Hook\APIGetAllowedParamsHook; |
6 | use MediaWiki\Api\Hook\APIQueryAfterExecuteHook; |
7 | use MediaWiki\MediaWikiServices; |
8 | |
9 | class 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 | } |