Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryCodeRevisions
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 6
756
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
90
 formatRow
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
182
 addReferenced
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\CodeReview\Api;
4
5use ApiBase;
6use ApiQueryBase;
7use ApiResult;
8use MediaWiki\Extension\CodeReview\Backend\CodeRepository;
9use MediaWiki\Extension\CodeReview\Backend\CodeRevision;
10use MediaWiki\Extension\CodeReview\UI\CodeRevisionListView;
11use stdClass;
12use Wikimedia\ParamValidator\ParamValidator;
13use Wikimedia\ParamValidator\TypeDef\IntegerDef;
14
15/**
16 * Created on July 06, 2010
17 *
18 * Copyright © 2010 Sam Reed
19 * Copyright © 2008 Bryan Tong Minh <Bryan.TongMinh@Gmail.com>
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 * http://www.gnu.org/copyleft/gpl.html
35 */
36
37class ApiQueryCodeRevisions extends ApiQueryBase {
38    /**
39     * @var array
40     */
41    private $props;
42
43    public function __construct( $query, $moduleName ) {
44        parent::__construct( $query, $moduleName, 'cr' );
45    }
46
47    /** @suppress SecurityCheck-SQLInjection See T201806 for more information */
48    public function execute() {
49        $this->getMain()->setCacheMode( 'anon-public-user-private' );
50
51        $this->checkUserRightsAny( 'codereview-use' );
52
53        $params = $this->extractRequestParams();
54
55        $this->props = array_flip( $params['prop'] );
56
57        $repo = CodeRepository::newFromName( $params['repo'] );
58
59        if ( !$repo ) {
60            $this->dieWithError( [ 'apierror-invalidrepo', wfEscapeWikiText( $params['repo'] ) ] );
61        }
62
63        $data = [];
64
65        $listview = new CodeRevisionListView( $repo );
66        if ( isset( $params['path'] ) && $params['path'] !== '' ) {
67            $listview->mPath = CodeRevisionListView::pathsToArray( $params['path'] );
68        }
69
70        $pager = $listview->getPager();
71
72        $revsSet = count( $params['revs'] );
73
74        if ( $revsSet ) {
75            $db = wfGetDB( DB_REPLICA );
76
77            $query = $pager->getQueryInfo();
78
79            $query['conds']['cr_id'] = $params['revs'];
80
81            $revisions = $db->select( $query['tables'], $query['fields'], $query['conds'],
82                __METHOD__, $query['options'], $query['join_conds'] );
83
84        } else {
85            if ( $params['start'] !== null ) {
86                $pager->setOffset( $params['start'] );
87            }
88
89            $limit = $params['limit'];
90            $pager->setLimit( $limit );
91
92            $pager->doQuery();
93
94            $revisions = $pager->getResult();
95        }
96
97        $count = 0;
98        $start = 0;
99        $defaultSort = $pager->getDefaultSort();
100        $result = $this->getResult();
101
102        foreach ( $revisions as $row ) {
103            if ( !$revsSet && $count == $limit ) {
104                $this->setContinueEnumParameter( 'start', $start );
105                break;
106            }
107
108            $data[] = $this->formatRow( $row, $repo, $result );
109            $start = $row->$defaultSort;
110            $count++;
111        }
112
113        ApiResult::setIndexedTagName( $data, 'revision' );
114        $result->addValue( 'query', $this->getModuleName(), $data );
115    }
116
117    /**
118     * @param stdClass $row
119     * @param CodeRepository $repo
120     * @param ApiResult $result
121     * @return array
122     */
123    private function formatRow( $row, $repo, $result ) {
124        $item = [];
125        if ( isset( $this->props['revid'] ) ) {
126            $item['revid'] = intval( $row->cr_id );
127        }
128        if ( isset( $this->props['status'] ) ) {
129            $item['status'] = $row->cr_status;
130        }
131        if ( isset( $this->props['commentcount'] ) ) {
132            $item['commentcount'] = $row->comments;
133        }
134        if ( isset( $this->props['path'] ) ) {
135            $item['path'] = $row->cr_path;
136        }
137        if ( isset( $this->props['message'] ) ) {
138            ApiResult::setContentValue( $item, 'message', $row->cr_message );
139        }
140        if ( isset( $this->props['author'] ) ) {
141            $item['author'] = $row->cr_author;
142        }
143        if ( isset( $this->props['timestamp'] ) ) {
144            $item['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cr_timestamp );
145        }
146        $rev = null;
147        if ( isset( $this->props['tags'] ) ) {
148            $rev = CodeRevision::newFromRow( $repo, $row );
149            $item['tags'] = $rev->getTags();
150            $result->setIndexedTagName( $item['tags'], 'tags' );
151        }
152        if ( isset( $this->props['followups'] ) ) {
153            if ( $rev === null ) {
154                $rev = CodeRevision::newFromRow( $repo, $row );
155            }
156            $item['followsup'] = $this->addReferenced( $rev );
157            $result->setIndexedTagName( $item['followsup'], 'followsup' );
158        }
159
160        if ( isset( $this->props['followedup'] ) ) {
161            if ( $rev === null ) {
162                $rev = CodeRevision::newFromRow( $repo, $row );
163            }
164            $item['followedup'] = $this->addReferenced( $rev );
165            $result->setIndexedTagName( $item['followedup'], 'followedup' );
166        }
167        return $item;
168    }
169
170    /**
171     * @param CodeRevision $rev
172     * @return array
173     */
174    protected function addReferenced( $rev ) {
175        $items = [];
176        foreach ( $rev->getFollowedUpRevisions() as $ref ) {
177            $refItem = [
178                'revid' => $ref->cr_id,
179                'status' => $ref->cr_status,
180                'timestamp' => wfTimestamp( TS_ISO_8601, $ref->cr_timestamp ),
181                'author' => $ref->cr_author ,
182            ];
183            ApiResult::setContentValue( $refItem, 'message', $ref->cr_message );
184
185            $items[] = $refItem;
186        }
187        return $items;
188    }
189
190    public function getAllowedParams() {
191        return [
192            'repo' => [
193                ParamValidator::PARAM_TYPE => 'string',
194                ParamValidator::PARAM_REQUIRED => true,
195            ],
196            'limit' => [
197                ParamValidator::PARAM_DEFAULT => 10,
198                ParamValidator::PARAM_TYPE => 'limit',
199                IntegerDef::PARAM_MIN => 1,
200                IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
201                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
202            ],
203            'path' => null,
204            'start' => [
205                ParamValidator::PARAM_TYPE => 'integer'
206            ],
207            'revs' => [
208                ParamValidator::PARAM_ISMULTI => true,
209                ParamValidator::PARAM_TYPE => 'integer',
210                IntegerDef::PARAM_MIN => 1,
211            ],
212            'prop' => [
213                ParamValidator::PARAM_ISMULTI => true,
214                ParamValidator::PARAM_DEFAULT => 'revid|status|author|timestamp',
215                ParamValidator::PARAM_TYPE => [
216                    'revid',
217                    'status',
218                    'commentcount',
219                    'path',
220                    'message',
221                    'author',
222                    'tags',
223                    'timestamp',
224                    'followups',
225                    'followedup',
226                ],
227            ],
228        ];
229    }
230
231    /**
232     * @inheritDoc
233     */
234    protected function getExamplesMessages() {
235        return [
236            'action=query&list=coderevisions&crrepo=MediaWiki'
237                => 'apihelp-query+coderevisions-example-1',
238            'action=query&list=coderevisions&crrepo=MediaWiki&crprop=revid|author|status|timestamp|tags'
239                => 'apihelp-query+coderevisions-example-2',
240        ];
241    }
242}