Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
58.00% |
29 / 50 |
|
66.67% |
2 / 3 |
CRAP | |
0.00% |
0 / 1 |
ApiEntryPoint | |
58.00% |
29 / 50 |
|
66.67% |
2 / 3 |
10.63 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
getContext | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
execute | |
51.16% |
22 / 43 |
|
0.00% |
0 / 1 |
7.91 |
1 | <?php |
2 | /** |
3 | * Entry point implementation for all %Action API queries, handled by ApiMain |
4 | * and ApiBase subclasses. |
5 | * |
6 | * @see /api.php The corresponding HTTP entry point. |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; if not, write to the Free Software Foundation, Inc., |
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
21 | * http://www.gnu.org/copyleft/gpl.html |
22 | * |
23 | * @file |
24 | * @ingroup entrypoint |
25 | * @ingroup API |
26 | */ |
27 | |
28 | namespace MediaWiki\Api; |
29 | |
30 | use LogicException; |
31 | use MediaWiki\Context\RequestContext; |
32 | use MediaWiki\EntryPointEnvironment; |
33 | use MediaWiki\HookContainer\HookRunner; |
34 | use MediaWiki\MediaWikiEntryPoint; |
35 | use MediaWiki\MediaWikiServices; |
36 | use MediaWiki\Title\Title; |
37 | use Throwable; |
38 | |
39 | /** |
40 | * Implementation of the API entry point, for web browser navigations, usually via an |
41 | * Action or SpecialPage subclass. |
42 | * |
43 | * This is used by bots to fetch content and information about the wiki, |
44 | * its pages, and its users. See <https://www.mediawiki.org/wiki/API> for more |
45 | * information. |
46 | * |
47 | * @see /api.php The corresponding HTTP entry point. |
48 | * @internal |
49 | */ |
50 | class ApiEntryPoint extends MediaWikiEntryPoint { |
51 | |
52 | public function __construct( |
53 | RequestContext $context, |
54 | EntryPointEnvironment $environment, |
55 | MediaWikiServices $services |
56 | ) { |
57 | parent::__construct( |
58 | $context, |
59 | $environment, |
60 | $services |
61 | ); |
62 | } |
63 | |
64 | /** |
65 | * Overwritten to narrow the return type to RequestContext |
66 | */ |
67 | protected function getContext(): RequestContext { |
68 | /** @var RequestContext $context */ |
69 | $context = parent::getContext(); |
70 | |
71 | // @phan-suppress-next-line PhanTypeMismatchReturnSuperType see $context in the constructor |
72 | return $context; |
73 | } |
74 | |
75 | /** |
76 | * Executes a request to the action API. |
77 | * |
78 | * It begins by constructing a new ApiMain using the parameter passed to it |
79 | * as an argument in the URL ('?action='). It then invokes "execute()" on the |
80 | * ApiMain object instance, which produces output in the format specified in |
81 | * the URL. |
82 | */ |
83 | protected function execute() { |
84 | // phpcs:ignore MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgTitle |
85 | global $wgTitle; |
86 | |
87 | $context = $this->getContext(); |
88 | $request = $this->getRequest(); |
89 | |
90 | $services = $this->getServiceContainer(); |
91 | |
92 | // PATH_INFO can be used for stupid things. We don't support it for api.php at |
93 | // all, so error out if it's present. (T128209) |
94 | $pathInfo = $this->environment->getServerInfo( 'PATH_INFO', '' ); |
95 | if ( $pathInfo != '' ) { |
96 | $correctUrl = wfAppendQuery( |
97 | wfScript( 'api' ), |
98 | $request->getQueryValuesOnly() |
99 | ); |
100 | $correctUrl = (string)$services->getUrlUtils()->expand( |
101 | $correctUrl, |
102 | PROTO_CANONICAL |
103 | ); |
104 | $this->header( |
105 | "Location: $correctUrl", |
106 | true, |
107 | 301 |
108 | ); |
109 | $this->print( |
110 | 'This endpoint does not support "path info", i.e. extra text ' . |
111 | 'between "api.php" and the "?". Remove any such text and try again.' |
112 | ); |
113 | $this->exit( 1 ); |
114 | } |
115 | |
116 | // Set a dummy $wgTitle, because $wgTitle == null breaks various things |
117 | // In a perfect world this wouldn't be necessary |
118 | $wgTitle = Title::makeTitle( |
119 | NS_SPECIAL, |
120 | 'Badtitle/dummy title for API calls set in api.php' |
121 | ); |
122 | |
123 | // RequestContext will read from $wgTitle, but it will also whine about it. |
124 | // In a perfect world this wouldn't be necessary either. |
125 | $context->setTitle( $wgTitle ); |
126 | |
127 | try { |
128 | // Construct an ApiMain with the arguments passed via the URL. What we get back |
129 | // is some form of an ApiMain, possibly even one that produces an error message, |
130 | // but we don't care here, as that is handled by the constructor. |
131 | $processor = new ApiMain( |
132 | $context, |
133 | true, |
134 | false |
135 | ); |
136 | |
137 | // Last chance hook before executing the API |
138 | ( new HookRunner( $services->getHookContainer() ) )->onApiBeforeMain( $processor ); |
139 | if ( !$processor instanceof ApiMain ) { |
140 | throw new LogicException( |
141 | 'ApiBeforeMain hook set $processor to a non-ApiMain class' |
142 | ); |
143 | } |
144 | } catch ( Throwable $e ) { |
145 | // Crap. Try to report the exception in API format to be friendly to clients. |
146 | ApiMain::handleApiBeforeMainException( $e ); |
147 | $processor = false; |
148 | } |
149 | |
150 | // Process data & print results |
151 | if ( $processor ) { |
152 | $processor->execute(); |
153 | } |
154 | } |
155 | } |