Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / api / ApiEntryPoint.php
blobc9ae63aa179c8fb4579f46fec973d8a54dcef22b
1 <?php
2 /**
3 * Entry point implementation for all %Action API queries, handled by ApiMain
4 * and ApiBase subclasses.
6 * @see /api.php The corresponding HTTP entry point.
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.
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.
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
23 * @file
24 * @ingroup entrypoint
25 * @ingroup API
28 namespace MediaWiki\Api;
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;
39 /**
40 * Implementation of the API entry point, for web browser navigations, usually via an
41 * Action or SpecialPage subclass.
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.
47 * @see /api.php The corresponding HTTP entry point.
48 * @internal
50 class ApiEntryPoint extends MediaWikiEntryPoint {
52 public function __construct(
53 RequestContext $context,
54 EntryPointEnvironment $environment,
55 MediaWikiServices $services
56 ) {
57 parent::__construct(
58 $context,
59 $environment,
60 $services
64 /**
65 * Overwritten to narrow the return type to RequestContext
66 * @return RequestContext
68 protected function getContext(): RequestContext {
69 /** @var RequestContext $context */
70 $context = parent::getContext();
72 // @phan-suppress-next-line PhanTypeMismatchReturnSuperType see $context in the constructor
73 return $context;
76 /**
77 * Executes a request to the action API.
79 * It begins by constructing a new ApiMain using the parameter passed to it
80 * as an argument in the URL ('?action='). It then invokes "execute()" on the
81 * ApiMain object instance, which produces output in the format specified in
82 * the URL.
84 protected function execute() {
85 // phpcs:ignore MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgTitle
86 global $wgTitle;
88 $context = $this->getContext();
89 $request = $this->getRequest();
91 $services = $this->getServiceContainer();
93 // PATH_INFO can be used for stupid things. We don't support it for api.php at
94 // all, so error out if it's present. (T128209)
95 $pathInfo = $this->environment->getServerInfo( 'PATH_INFO', '' );
96 if ( $pathInfo != '' ) {
97 $correctUrl = wfAppendQuery(
98 wfScript( 'api' ),
99 $request->getQueryValuesOnly()
101 $correctUrl = (string)$services->getUrlUtils()->expand(
102 $correctUrl,
103 PROTO_CANONICAL
105 $this->header(
106 "Location: $correctUrl",
107 true,
110 $this->print(
111 'This endpoint does not support "path info", i.e. extra text ' .
112 'between "api.php" and the "?". Remove any such text and try again.'
114 $this->exit( 1 );
117 // Set a dummy $wgTitle, because $wgTitle == null breaks various things
118 // In a perfect world this wouldn't be necessary
119 $wgTitle = Title::makeTitle(
120 NS_SPECIAL,
121 'Badtitle/dummy title for API calls set in api.php'
124 // RequestContext will read from $wgTitle, but it will also whine about it.
125 // In a perfect world this wouldn't be necessary either.
126 $context->setTitle( $wgTitle );
128 try {
129 // Construct an ApiMain with the arguments passed via the URL. What we get back
130 // is some form of an ApiMain, possibly even one that produces an error message,
131 // but we don't care here, as that is handled by the constructor.
132 $processor = new ApiMain(
133 $context,
134 true,
135 false
138 // Last chance hook before executing the API
139 ( new HookRunner( $services->getHookContainer() ) )->onApiBeforeMain( $processor );
140 if ( !$processor instanceof ApiMain ) {
141 throw new LogicException(
142 'ApiBeforeMain hook set $processor to a non-ApiMain class'
145 } catch ( Throwable $e ) {
146 // Crap. Try to report the exception in API format to be friendly to clients.
147 ApiMain::handleApiBeforeMainException( $e );
148 $processor = false;
151 // Process data & print results
152 if ( $processor ) {
153 $processor->execute();