Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.66% covered (warning)
68.66%
46 / 67
33.33% covered (danger)
33.33%
2 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoQueryAPI
68.66% covered (warning)
68.66%
46 / 67
33.33% covered (danger)
33.33%
2 / 6
16.43
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
85.71% covered (warning)
85.71%
24 / 28
0.00% covered (danger)
0.00%
0 / 1
7.14
 getAllowedParams
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
1
 getParamDescription
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getExamples
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Adds and handles the 'cargoquery' action to the MediaWiki API.
4 *
5 * @ingroup Cargo
6 * @author Yaron Koren
7 */
8
9class CargoQueryAPI extends ApiBase {
10
11    public function __construct( $query, $moduleName ) {
12        parent::__construct( $query, $moduleName );
13    }
14
15    public function execute() {
16        $params = $this->extractRequestParams();
17        $tablesStr = $params['tables'];
18        $fieldsStr = $params['fields'];
19        $whereStr = $params['where'];
20        $joinOnStr = $params['join_on'];
21        $orderByStr = $params['order_by'];
22        $groupByStr = $params['group_by'];
23        $havingStr = $params['having'];
24        $limitStr = $params['limit'];
25        $offsetStr = $params['offset'];
26
27        if ( $tablesStr == '' ) {
28            $this->dieWithError( 'The tables must be specified', 'param_substr' );
29        }
30
31        // Allow operators to control how many Cargo queries may be run via the API or Special:CargoQuery (T331689)
32        if ( $this->getUser()->pingLimiter( 'cargo-query' ) ) {
33            $this->dieWithError( 'apierror-ratelimited' );
34        }
35
36        $sqlQuery = CargoSQLQuery::newFromValues( $tablesStr, $fieldsStr, $whereStr, $joinOnStr,
37                $groupByStr, $havingStr, $orderByStr, $limitStr, $offsetStr );
38
39        foreach ( $sqlQuery->mFieldStringAliases as $fieldStrAlias ) {
40            if ( $fieldStrAlias[0] == '_' ) {
41                $this->dieWithError( [ 'apierror-cargoquery-invalidfieldalias', $fieldStrAlias ] );
42            }
43        }
44
45        try {
46            $queryResults = $sqlQuery->run();
47        } catch ( Exception $e ) {
48            $this->dieWithError( $e, 'db_error' );
49        }
50
51        // Format data as the API requires it.
52        $formattedData = [];
53        foreach ( $queryResults as $row ) {
54            $formattedData[] = [ 'title' => $row ];
55        }
56
57        // Set top-level elements.
58        $result = $this->getResult();
59        $result->setIndexedTagName( $formattedData, 'p' );
60        $result->addValue( null, $this->getModuleName(), $formattedData );
61    }
62
63    protected function getAllowedParams() {
64        return [
65            'limit' => [
66                ApiBase::PARAM_TYPE => 'limit',
67                ApiBase::PARAM_DFLT => 50,
68                ApiBase::PARAM_MIN => 1,
69                ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
70                ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
71            ],
72            'tables' => null,
73            'fields' => null,
74            'where' => null,
75            'join_on' => null,
76            'group_by' => null,
77            'having' => null,
78            'order_by' => null,
79            'offset' => [
80                ApiBase::PARAM_TYPE => 'integer',
81                ApiBase::PARAM_DFLT => 0,
82                ApiBase::PARAM_MIN => 0,
83            ],
84        ];
85    }
86
87    protected function getParamDescription() {
88        return [
89            'tables' => 'The Cargo database table or tables on which to search',
90            'fields' => 'The table field(s) to retrieve',
91            'where' => 'The conditions for the query, corresponding to an SQL WHERE clause',
92            'join_on' => 'Conditions for joining multiple tables, corresponding to an SQL JOIN ON clause',
93            'order_by' => 'The order of results, corresponding to an SQL ORDER BY clause',
94            'group_by' => 'Field(s) on which to group results, corresponding to an SQL GROUP BY clause',
95            'having' => 'Conditions for grouped values, corresponding to an SQL HAVING clause',
96            'limit' => 'A limit on the number of results returned',
97            'offset' => 'The query offset number',
98        ];
99    }
100
101    protected function getDescription() {
102        return 'An SQL-style query used for data tables, provided by the Cargo extension '
103            . '(https://www.mediawiki.org/Extension:Cargo)';
104    }
105
106    protected function getExamples() {
107        return [
108            'api.php?action=cargoquery&tables=Items&fields=_pageName=Item,Source,Date=Publication_date'
109            . '&where=Source+LIKE+\'%New%\'&order_by=Date&limit=100'
110        ];
111    }
112
113}