Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
72.00% covered (warning)
72.00%
36 / 50
50.00% covered (danger)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiStreamConfigs
72.00% covered (warning)
72.00%
36 / 50
50.00% covered (danger)
50.00%
3 / 6
9.40
0.00% covered (danger)
0.00%
0 / 1
 execute
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
 getAllowedParams
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCustomPrinter
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 multiParamToAssocArray
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\EventStreamConfig;
4
5use MediaWiki\Api\ApiBase;
6use MediaWiki\Api\ApiResult;
7use MediaWiki\MediaWikiServices;
8use Wikimedia\ParamValidator\ParamValidator;
9
10/**
11 * Enables requesting allowed MediaWiki configs via the API.
12 * Usage:
13 *
14 * Get stream config settings
15 *   GET /w/api.php?format=json&action=streamconfigs
16 *
17 * Get stream config settings for specified streams
18 *   GET /w/api.php?format=json&action=streamconfigs&streams=my-stream1|my-stream2
19 */
20class ApiStreamConfigs extends ApiBase {
21    // 10 minutes
22    private const CACHE_MAX_AGE = 600;
23
24    /**
25     * API query param used to specify target streams to get from Config
26     */
27    private const API_PARAM_STREAMS = 'streams';
28
29    /**
30     * API query param used to restrict stream config entry results to
31     * those that have settings that match these constraints.
32     * This is expected to be given as a multi array of key=val pairs.  E.g.
33     *   constraints=event_service_name=eventgate-main|other_setting=other_value
34     * This would be parsed into
35     * @code
36     *   [
37     *       'event_service_name' => 'eventgate-main',
38     *       'other_setting' => 'other_value'
39     *   ]
40     * @endcode
41     *
42     * And be used to filter for stream config entries that have these settings.
43     */
44    private const API_PARAM_CONSTRAINTS = 'constraints';
45
46    /**
47     * @deprecated since 1.41
48     */
49    private const API_PARAM_ALL_SETTINGS = 'all_settings';
50
51    /**
52     * @inheritDoc
53     */
54    public function execute() {
55        $this->getMain()->setCacheMode( 'public' );
56        $this->getMain()->setCacheMaxAge( self::CACHE_MAX_AGE );
57
58        $targetStreams = $this->getParameter( self::API_PARAM_STREAMS );
59        $constraints = $this->getParameter( self::API_PARAM_CONSTRAINTS );
60
61        $settingsConstraints = $constraints ? self::multiParamToAssocArray( $constraints ) : null;
62
63        $streamConfigs = MediaWikiServices::getInstance()->getService(
64            'EventStreamConfig.StreamConfigs'
65        );
66
67        $result = $streamConfigs->get(
68            $targetStreams,
69            $settingsConstraints
70        );
71
72        // Ensure that empty stream configs are serialized as objects ({}) and not as lists ([]).
73        //
74        // See https://phabricator.wikimedia.org/T259917 and
75        // https://phabricator.wikimedia.org/T323032 for additional context.
76        foreach ( $result as &$value ) {
77            ApiResult::setArrayType( $value, 'assoc' );
78        }
79
80        ApiResult::setArrayType( $result, 'assoc' );
81
82        $this->getResult()->addValue( null, "streams", $result );
83    }
84
85    /**
86     * @inheritDoc
87     */
88    public function getAllowedParams() {
89        return [
90            self::API_PARAM_STREAMS => [
91                ParamValidator::PARAM_ISMULTI => true,
92                ParamValidator::PARAM_ISMULTI_LIMIT1 => 250,
93            ],
94            self::API_PARAM_CONSTRAINTS => [
95                ParamValidator::PARAM_ISMULTI => true,
96            ],
97            self::API_PARAM_ALL_SETTINGS => [
98                ParamValidator::PARAM_DEPRECATED => true,
99                ParamValidator::PARAM_TYPE => 'boolean',
100            ],
101        ];
102    }
103
104    /**
105     * @inheritDoc
106     */
107    protected function getExamplesMessages() {
108        return [
109            'action=streamconfigs&' . self::API_PARAM_STREAMS .
110            '=mediawiki.page-view|mediawiki.button-click' =>
111                    'apihelp-streamconfigs-example-1',
112
113            'action=streamconfigs&' . self::API_PARAM_STREAMS .
114            '=mediawiki.button-click' =>
115                    'apihelp-streamconfigs-example-2',
116
117            'action=streamconfigs&' . self::API_PARAM_STREAMS .
118            '=mediawiki.button-click' .
119            '&constraints=event_service_name=eventgate-main' =>
120                    'apihelp-streamconfigs-example-3',
121        ];
122    }
123
124    /**
125     * @inheritDoc
126     */
127    public function getHelpUrls() {
128        return 'https://www.mediawiki.org/wiki/Extension:EventStreamConfig';
129    }
130
131    /**
132     * @inheritDoc
133     */
134    public function getCustomPrinter() {
135        return new ApiFormatJsonVersion2( $this->getMain(), 'json' );
136    }
137
138    /**
139     * Parses a MULTI PARAM value into an assoc array.
140     *
141     * For example, the query string parameter "my_param=key1=val1|key2[key3]=val2" will be parsed into the following:
142     *
143     * ```
144     * [
145     *     'key1' => 'val1',
146     *     'key2' => [
147     *         'key3' => 'val2',
148     *     ],
149     * ]
150     * ```
151     *
152     * @param array $multiParamArray List of key=val string pairs
153     * @return array
154     */
155    private static function multiParamToAssocArray( array $multiParamArray ) {
156        return array_reduce(
157            $multiParamArray,
158            static function ( $carry, $elementString ) {
159                return array_merge_recursive( $carry, wfCgiToArray( $elementString ) );
160            },
161            []
162        );
163    }
164}