API:Calling internally

From mediawiki.org
Revision as of 20:15, 27 March 2015 by SPage (WMF) (talk | contribs) (clarify this is PHP code, wordsmith)

Sometimes other PHP code may wish to use the data access and aggregation functionality of the API.

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 existing request from the user, prepare request parameters using DerivativeRequest class. All parameters are the same as if making the request over the web.

$params = new DerivativeRequest( 
        $this->getRequest(),
        array(
	  'action' => 'query',
	  'list' => 'allpages',
	  'apnamespace' => 0,
	   'aplimit' => 10,
	  'apprefix' => $search),
        true
);

2) Create and execute ApiMain instance. Because the parameter is an instance of 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 send another parameter = true, when creating the ApiMain object. Like so:

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

You may also need to send an edit token along as the last parameter when making edits or changes. You can get the edit token like so:

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

3) Get the resulting data array.

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

Here is a complete example taken from Extension:WikiLove (as of r112758):

       $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 // was posted?
            ),
            true // enable write?
        );

        $api->execute();

If there is no user request context, you can use FauxRequest instead of DerivativeRequest. Using FauxRequest for write operations without passing request context causes bug 34838.

If passed invalid parameters, the 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