MediaWiki  master
ActionModuleBasedHandler.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Rest\Handler;
4 
5 use ApiBase;
6 use ApiMain;
7 use ApiMessage;
9 use FauxRequest;
10 use IApiMessage;
16 use RequestContext;
17 use WebResponse;
23 
29 abstract class ActionModuleBasedHandler extends Handler {
30 
34  private $session = null;
35 
39  private $apiMain = null;
40 
41  protected function getUser() {
42  return $this->getApiMain()->getUser();
43  }
44 
48  protected function getSession() {
49  if ( !$this->session ) {
50  $this->session = $this->getApiMain()->getRequest()->getSession();
51  }
52 
53  return $this->session;
54  }
55 
61  public function setApiMain( ApiMain $apiMain ) {
62  $this->apiMain = $apiMain;
63  }
64 
68  public function getApiMain() {
69  if ( $this->apiMain ) {
70  return $this->apiMain;
71  }
72 
74  $session = $context->getRequest()->getSession();
75 
76  // NOTE: This being a FauxRequest instance triggers special case behavior
77  // in ApiMain, causing ApiMain::isInternalMode() to return true. Among other things,
78  // this causes ApiMain to throw errors rather than encode them in the result data.
79  $fauxRequest = new FauxRequest( [], true, $session );
80  $fauxRequest->setSessionId( $session->getSessionId() );
81 
82  $fauxContext = new RequestContext();
83  $fauxContext->setRequest( $fauxRequest );
84  $fauxContext->setUser( $context->getUser() );
85  $fauxContext->setLanguage( $context->getLanguage() );
86 
87  $this->apiMain = new ApiMain( $fauxContext, true );
88  return $this->apiMain;
89  }
90 
98  public function overrideActionModule( string $name, string $group, ApiBase $module ) {
99  $this->getApiMain()->getModuleManager()->addModule(
100  $name,
101  $group,
102  [
103  'class' => get_class( $module ),
104  'factory' => function () use ( $module ) {
105  return $module;
106  }
107  ]
108  );
109  }
110 
120  public function execute() {
121  $apiMain = $this->getApiMain();
122 
123  $params = $this->getActionModuleParameters();
125 
126  foreach ( $params as $key => $value ) {
127  $request->setVal( $key, $value );
128  }
129 
130  try {
131  // NOTE: ApiMain detects the this to be an internal call, so it will throw
132  // ApiUsageException rather than putting error messages into the result.
133  $apiMain->execute();
134  } catch ( ApiUsageException $ex ) {
135  // use a fake loop to throw the first error
136  foreach ( $ex->getStatusValue()->getErrorsByType( 'error' ) as $error ) {
137  $msg = ApiMessage::create( $error );
138  $this->throwHttpExceptionForActionModuleError( $msg, $ex->getCode() ?: 400 );
139  }
140 
141  // This should never happen, since ApiUsageExceptions should always
142  // have errors in their Status object.
143  throw new HttpException(
144  'Unmapped action module error: ' . $ex->getMessage(),
145  $ex->getCode()
146  );
147  }
148 
149  $actionModuleResult = $apiMain->getResult()->getResultData( null, [ 'Strip' => 'all' ] );
150 
151  // construct result
152  $resultData = $this->mapActionModuleResult( $actionModuleResult );
153 
154  $response = $this->getResponseFactory()->createFromReturnValue( $resultData );
155 
157  $apiMain->getRequest()->response(),
158  $actionModuleResult,
159  $response
160  );
161 
162  return $response;
163  }
164 
174  abstract protected function getActionModuleParameters();
175 
184  abstract protected function mapActionModuleResult( array $data );
185 
202  protected function mapActionModuleResponse(
203  WebResponse $actionModuleResponse,
204  array $actionModuleResult,
205  Response $response
206  ) {
207  // TODO: map status, headers, cookies, etc
208  }
209 
228  protected function throwHttpExceptionForActionModuleError( IApiMessage $msg, $statusCode = 400 ) {
229  // override to supply mappings
230 
231  throw new LocalizedHttpException(
232  $this->makeMessageValue( $msg ),
233  $statusCode,
234  // Include the original error code in the response.
235  // This makes it easier to track down the original cause of the error,
236  // and allows more specific mappings to be added to
237  // implementations of throwHttpExceptionForActionModuleError() provided by
238  // subclasses
239  [ 'actionModuleErrorCode' => $msg->getApiCode() ]
240  );
241  }
242 
250  protected function makeMessageValue( IApiMessage $msg ) {
251  $params = [];
252 
253  // TODO: find a better home for the parameter mapping logic
254  foreach ( $msg->getParams() as $p ) {
255  $params[] = $this->makeMessageParam( $p );
256  }
257 
258  return new MessageValue( $msg->getKey(), $params );
259  }
260 
266  private function makeMessageParam( $param ) {
267  if ( is_array( $param ) ) {
268  foreach ( $param as $type => $value ) {
269  if ( $type === 'list' ) {
270  $paramList = [];
271 
272  foreach ( $value as $v ) {
273  $paramList[] = $this->makeMessageParam( $v );
274  }
275 
276  return new ListParam( ParamType::TEXT, $paramList );
277  } else {
278  return new ScalarParam( $type, $value );
279  }
280  }
281  } else {
282  return new ScalarParam( ParamType::TEXT, $param );
283  }
284  }
285 
286 }
MediaWiki\Rest\Handler\ActionModuleBasedHandler\getApiMain
getApiMain()
Definition: ActionModuleBasedHandler.php:68
ApiUsageException\getStatusValue
getStatusValue()
Fetch the error status.
Definition: ApiUsageException.php:107
MediaWiki\Rest\Handler\ActionModuleBasedHandler\$session
Session null $session
Definition: ActionModuleBasedHandler.php:34
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:48
MediaWiki\Rest\Handler
Definition: AbstractContributionHandler.php:3
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:35
ApiUsageException
Exception used to abort API execution with an error.
Definition: ApiUsageException.php:29
MediaWiki\Rest\Handler\ActionModuleBasedHandler
Base class for REST handlers that are implemented by mapping to an existing ApiModule.
Definition: ActionModuleBasedHandler.php:29
MediaWiki\Rest\Handler\ActionModuleBasedHandler\makeMessageValue
makeMessageValue(IApiMessage $msg)
Constructs a MessageValue from an IApiMessage.
Definition: ActionModuleBasedHandler.php:250
MediaWiki\Rest\Handler\getResponseFactory
getResponseFactory()
Get the ResponseFactory which can be used to generate Response objects.
Definition: Handler.php:151
MediaWiki\Rest\Handler\$request
RequestInterface $request
Definition: Handler.php:28
MessageSpecifier\getKey
getKey()
Returns the message key.
IApiMessage\getApiCode
getApiCode()
Returns a machine-readable code for use by the API.
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:79
Wikimedia\Message\ScalarParam
Value object representing a message parameter holding a single value.
Definition: ScalarParam.php:12
IApiMessage
Interface for messages with machine-readable data for use by the API.
Definition: IApiMessage.php:39
MediaWiki\Rest\Handler\ActionModuleBasedHandler\getSession
getSession()
Definition: ActionModuleBasedHandler.php:48
Wikimedia\Message\MessageValue
Value object representing a message for i18n.
Definition: MessageValue.php:16
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:52
MediaWiki\Rest\Handler
Base class for REST route handlers.
Definition: Handler.php:16
MessageSpecifier\getParams
getParams()
Returns the message parameters.
ApiMessage
Extension of Message implementing IApiMessage @newable.
Definition: ApiMessage.php:27
MediaWiki\Rest\Handler\ActionModuleBasedHandler\setApiMain
setApiMain(ApiMain $apiMain)
Set main action API entry point for testing.
Definition: ActionModuleBasedHandler.php:61
MediaWiki\Rest\Handler\ActionModuleBasedHandler\overrideActionModule
overrideActionModule(string $name, string $group, ApiBase $module)
Overrides an action API module.
Definition: ActionModuleBasedHandler.php:98
MediaWiki\Rest\Handler\ActionModuleBasedHandler\mapActionModuleResponse
mapActionModuleResponse(WebResponse $actionModuleResponse, array $actionModuleResult, Response $response)
Transfers relevant information, such as header values, from the WebResponse constructed by the action...
Definition: ActionModuleBasedHandler.php:202
MediaWiki\Session\Session
Manages data for an authenticated session.
Definition: Session.php:48
ApiMain\getResult
getResult()
Get the ApiResult object associated with current request.
Definition: ApiMain.php:338
MediaWiki\Rest\Response
Definition: Response.php:8
MediaWiki\Rest\Handler\ActionModuleBasedHandler\throwHttpExceptionForActionModuleError
throwHttpExceptionForActionModuleError(IApiMessage $msg, $statusCode=400)
Throws a HttpException for a given IApiMessage that represents an error.
Definition: ActionModuleBasedHandler.php:228
RequestContext
Group all the pieces relevant to the context of a request into one instance @newable.
Definition: RequestContext.php:39
ApiMessage\create
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
Definition: ApiMessage.php:42
MediaWiki\Session\Session\getSessionId
getSessionId()
Returns the SessionId object.
Definition: Session.php:89
MediaWiki\Rest\Handler\ActionModuleBasedHandler\getUser
getUser()
Definition: ActionModuleBasedHandler.php:41
MediaWiki\Rest\Handler\ActionModuleBasedHandler\$apiMain
ApiMain null $apiMain
Definition: ActionModuleBasedHandler.php:39
MediaWiki\Rest\HttpException
This is the base exception class for non-fatal exceptions thrown from REST handlers.
Definition: HttpException.php:12
ApiMain\execute
execute()
Execute api request.
Definition: ApiMain.php:537
MediaWiki\Rest\Handler\ActionModuleBasedHandler\execute
execute()
Main execution method, implemented to delegate execution to ApiMain.
Definition: ActionModuleBasedHandler.php:120
IContextSource\getUser
getUser()
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:454
Wikimedia\Message\ListParam
Value object representing a message parameter that consists of a list of values.
Definition: ListParam.php:12
IContextSource\getRequest
getRequest()
MediaWiki\Rest\Handler\ActionModuleBasedHandler\makeMessageParam
makeMessageParam( $param)
Definition: ActionModuleBasedHandler.php:266
MediaWiki\$context
IContextSource $context
Definition: MediaWiki.php:40
WebResponse
Allow programs to request this object from WebRequest::response() and handle all outputting (or lack ...
Definition: WebResponse.php:30
Wikimedia\Message\MessageParam
Value object representing a message parameter that consists of a list of values.
Definition: MessageParam.php:10
MediaWiki\Rest\Handler\ActionModuleBasedHandler\mapActionModuleResult
mapActionModuleResult(array $data)
Maps an action API result to a REST API result.
MediaWiki\Rest\Handler\ActionModuleBasedHandler\getActionModuleParameters
getActionModuleParameters()
Maps a REST API request to an action API request.
IContextSource\getLanguage
getLanguage()
MediaWiki\Rest\LocalizedHttpException
@newable
Definition: LocalizedHttpException.php:10
Wikimedia\Message\ParamType
The constants used to specify parameter types.
Definition: ParamType.php:11
$type
$type
Definition: testCompression.php:52