API:Calling internally

From MediaWiki.org
Jump to: navigation, search
Language:Project:Language policy English  • 日本語
Tools clipart.png This page is part of the MediaWiki action API documentation.
MediaWiki APIsAPI:Main page

MediaWiki action API

v · d · e

Sometimes other PHP code may wish to use the data access and aggregation functionality of the action API. Rather than making an HTTP network request to the same server, you can make a call within PHP.

Calling the API internally is often a sign that some functionality should be refactored into a backend class that can be used both by your code and by the API module. See Architecture guidelines#Separation of concerns — UI and business logic.
If your code is making predetermined edits and does not need to to sanitize user input, go through the abuse filter, etc., consider using WikiPage::doEditContent() instead of an API request.

The steps are:

1) If you are executing in the context of an existing request from a user, prepare request parameters using the DerivativeRequest class.

  • Its constructor's first parameter is the request to derive from.
  • Its constructor's second parameter is an array of API parameters that is the same as if making the request over the web.
  • Its constructor's third parameter is optional, specify true to treat the API call as a POST when the API module you're invoking requires POST requests.

This sample code issues the 'allpages' list query starting at the letter 'M'. This is a simple query, not requiring a user or POST.

$params = new DerivativeRequest(
    $this->getRequest(), // Fallback upon $wgRequest if you can't access context.
    array(
        'action' => 'query',
        'list' => 'allpages',
        'apnamespace' => 0,
        'aplimit' => 10, 
        'apprefix' => 'M'
    )  
);

If you need to provide an edit token as an API parameter when making edits or other changes, you can get the edit token like so:

$user = $this->getUser(); // Or User::newFromName, etc.
$token = $user->getEditToken();

2) Create an ApiMain instance. then execute the API request. Because the parameter is a DerivativeRequest object, ApiMain will not execute any formatting printers, nor will it handle any errors. A parameter error or any other internal error will cause an exception that may be caught in the calling code.

$api = new ApiMain( $params );
$api->execute();

Important: If you want to create or edit pages, you have to pass true as a second parameter when creating the ApiMain object:

$api = new ApiMain( $params, true ); // default is false
$api->execute();

3) Get the resulting data array.

$data = $api->getResult()->getResultData();

Here is a complete example taken from Extension:WikiLoveExtension:WikiLove (as of r112758). It adds text to a page, so it must run when handling a logged-in user's HTTP request.

       $api = new ApiMain(
            new DerivativeRequest(
                $this->getRequest(), // Fallback upon $wgRequest if you can't access context
                array(
                    'action'     => 'edit',
                    'title'      => $talk->getFullText(),
                    'appendtext' => ( $talk->exists() 
                                      ? "\n\n" 
                                      : '' ) .
                        wfMsgForContent( 'newsectionheaderdefaultlevel', 
                          $params['subject'] )
                        . "\n\n" . $params['text'],
                    'token'      => $params['token'],
                    'summary'    => wfMsgForContent( 'wikilove-summary',
                        $wgParser->stripSectionName( $params['subject'] ) ),
                    'notminor'   => true
                ),
                true // treat this as a POST
            ),
            true // Enable write.
        );

        $api->execute();

FauxRequest[edit]

The example above creates a DerivativeRequest RequestContextManual:RequestContext.php. This "inherits" some of the original request, such as IP and request headers that are set when MediaWiki is doing an action on behalf of a user, typically when handling a web request. If there is no user request context, for example when invoking the action API from a system process, or if you want to make a completely separate internal request, then you can use FauxRequest instead. Using FauxRequest for write operations without passing request context causes bug T36838.

Error handling[edit]

If passed invalid parameters, the action API may throw a UsageException. If its possible for your code to send an invalid parameter, you should probably call the API from inside a try/catch block

See also[edit]