Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 83 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
SpecialRestSandbox | |
0.00% |
0 / 83 |
|
0.00% |
0 / 7 |
272 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getApiSpecs | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isListed | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSpecUrl | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
30 | |||
execute | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
12 | |||
showForm | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Specials; |
22 | |
23 | use MediaWiki\Html\Html; |
24 | use MediaWiki\HTMLForm\HTMLForm; |
25 | use MediaWiki\MainConfigNames; |
26 | use MediaWiki\SpecialPage\SpecialPage; |
27 | use MediaWiki\Utils\UrlUtils; |
28 | |
29 | /** |
30 | * A special page showing a Swagger UI for exploring REST APIs. |
31 | * |
32 | * @ingroup SpecialPage |
33 | * @since 1.43 |
34 | */ |
35 | class SpecialRestSandbox extends SpecialPage { |
36 | |
37 | private UrlUtils $urlUtils; |
38 | |
39 | public function __construct( UrlUtils $urlUtils ) { |
40 | parent::__construct( 'RestSandbox' ); |
41 | |
42 | $this->urlUtils = $urlUtils; |
43 | } |
44 | |
45 | /** |
46 | * Returns the available choices for APIs to explore. |
47 | * |
48 | * @see MainConfigSchema::RestSandboxSpecs for the structure of the array |
49 | * |
50 | * @return array[] |
51 | */ |
52 | private function getApiSpecs(): array { |
53 | return $this->getConfig()->get( MainConfigNames::RestSandboxSpecs ); |
54 | } |
55 | |
56 | public function isListed() { |
57 | // Hide the special pages if there are no APIs to explore. |
58 | return $this->getApiSpecs() !== []; |
59 | } |
60 | |
61 | protected function getGroupName() { |
62 | return 'wiki'; |
63 | } |
64 | |
65 | private function getSpecUrl( ?string $apiId ): ?string { |
66 | $apiSpecs = $this->getApiSpecs(); |
67 | |
68 | if ( $apiId !== null && $apiId !== '' ) { |
69 | $spec = $apiSpecs[$apiId] ?? null; |
70 | } else { |
71 | $spec = reset( $apiSpecs ) ?: null; |
72 | } |
73 | |
74 | if ( !$spec ) { |
75 | return null; |
76 | } |
77 | |
78 | return $this->urlUtils->expand( $spec['url'] ); |
79 | } |
80 | |
81 | public function execute( $sub ) { |
82 | $this->setHeaders(); |
83 | $out = $this->getOutput(); |
84 | $this->addHelpLink( 'Help:RestSandbox' ); |
85 | |
86 | $apiId = $this->getRequest()->getText( 'api', $sub ?? '' ); |
87 | $specUrl = $this->getSpecUrl( $apiId ); |
88 | |
89 | $apiSpecs = $this->getApiSpecs(); |
90 | |
91 | $out->addJsConfigVars( [ |
92 | 'specUrl' => $specUrl |
93 | ] ); |
94 | |
95 | $out->addModuleStyles( [ |
96 | 'mediawiki.special', |
97 | 'mediawiki.hlist', |
98 | 'mediawiki.special.restsandbox.styles' |
99 | ] ); |
100 | |
101 | if ( !$apiSpecs ) { |
102 | $out->addHTML( Html::errorBox( |
103 | $out->msg( 'restsandbox-no-specs-configured' )->parse() |
104 | ) ); |
105 | return; |
106 | } |
107 | |
108 | $this->showForm( $apiSpecs ); |
109 | |
110 | if ( !$specUrl ) { |
111 | $out->addHTML( Html::errorBox( |
112 | $out->msg( 'restsandbox-no-such-api' )->params( $apiId )->parse() |
113 | ) ); |
114 | return; |
115 | } |
116 | |
117 | $out->addModules( [ |
118 | 'mediawiki.special.restsandbox' |
119 | ] ); |
120 | |
121 | $out->addHTML( Html::openElement( 'div', [ 'id' => 'mw-restsandbox' ] ) ); |
122 | |
123 | // Hidden when JS is available |
124 | $out->wrapWikiMsg( |
125 | Html::element( |
126 | 'div', |
127 | [ 'class' => [ 'mw-restsandbox-client-nojs', 'error', ], ], |
128 | "\n$1\n" |
129 | ), |
130 | 'restsandbox-jsonly' |
131 | ); |
132 | |
133 | // To be replaced by Swagger UI. |
134 | $out->addElement( 'div', [ 'id' => 'mw-restsandbox-swagger-ui' ] ); |
135 | |
136 | $out->addHTML( Html::closeElement( 'div' ) ); // #mw-restsandbox |
137 | } |
138 | |
139 | private function showForm( array $apiSpecs ) { |
140 | $apis = []; |
141 | |
142 | foreach ( $apiSpecs as $key => $spec ) { |
143 | if ( isset( $spec['msg'] ) ) { |
144 | $text = $this->msg( $spec['msg'] )->plain(); |
145 | } elseif ( isset( $spec['name'] ) ) { |
146 | $text = $spec['name']; |
147 | } else { |
148 | $text = $key; |
149 | } |
150 | |
151 | $apis[$text] = $key; |
152 | } |
153 | |
154 | $formDescriptor = [ |
155 | 'intro' => [ |
156 | 'type' => 'info', |
157 | 'raw' => true, |
158 | 'default' => $this->msg( 'restsandbox-text' )->parseAsBlock() |
159 | ], |
160 | 'api' => [ |
161 | 'type' => 'select', |
162 | 'name' => 'api', |
163 | 'label-message' => 'restsandbox-select-api', |
164 | 'options' => $apis |
165 | ], |
166 | 'title' => [ |
167 | 'type' => 'hidden', |
168 | 'name' => 'title', |
169 | 'default' => $this->getPageTitle()->getPrefixedDBkey() |
170 | ], |
171 | ]; |
172 | |
173 | $action = $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ); |
174 | |
175 | $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ); |
176 | $htmlForm->setAction( $action ); |
177 | $htmlForm->setMethod( 'GET' ); |
178 | $htmlForm->setId( 'mw-restsandbox-form' ); |
179 | $htmlForm->prepareForm()->displayForm( false ); |
180 | } |
181 | } |