mediawiki-extensions-Scribunto/common/ApiScribuntoConsole.php
Brad Jorsch 9443fda132 Add i18n for API module help and mark ApiScribuntoConsole as internal
MediaWiki core change I04b1a384 added support for i18n of API module
help. This takes advantage of that while still maintaining backwards
compatibility with earlier versions of MediaWiki.

Once support for MediaWiki before 1.25 is dropped, the methods marked
deprecated in this patch may be removed.

Change-Id: I67395aff48185f3e09da31b51a08aa2541fe6a17
2014-11-03 21:10:19 +00:00

170 lines
4.5 KiB
PHP

<?php
/**
* API module for serving debug console requests on the edit page
*/
class ApiScribuntoConsole extends ApiBase {
const SC_MAX_SIZE = 500000;
const SC_SESSION_EXPIRY = 3600;
public function execute() {
$params = $this->extractRequestParams();
$title = Title::newFromText( $params['title'] );
if ( !$title ) {
$this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
}
if ( $params['session'] ) {
$sessionId = $params['session'];
} else {
$sessionId = mt_rand( 0, 0x7fffffff );
}
global $wgUser;
$sessionKey = wfMemcKey( 'scribunto-console', $wgUser->getId(), $sessionId );
$cache = ObjectCache::getInstance( CACHE_ANYTHING );
$session = null;
$sessionIsNew = false;
if ( $params['session'] ) {
$session = $cache->get( $sessionKey );
}
if ( !isset( $session['version'] ) ) {
$session = $this->newSession();
$sessionIsNew = true;
}
// Create a variable holding the session which will be stored if there
// are no errors. If there are errors, we don't want to store the current
// question to the state builder array, since that will cause subsequent
// requests to fail.
$newSession = $session;
if ( !empty( $params['clear'] ) ) {
$newSession['size'] -= strlen( implode( '', $newSession['questions'] ) );
$newSession['questions'] = array();
$session['questions'] = array();
}
if ( strlen( $params['question'] ) ) {
$newSession['size'] += strlen( $params['question'] );
$newSession['questions'][] = $params['question'];
}
if ( $params['content'] ) {
$newSession['size'] += strlen( $params['content'] ) - strlen( $newSession['content'] );
$newSession['content'] = $params['content'];
}
if ( $newSession['size'] > self::SC_MAX_SIZE ) {
$this->dieUsage(
$this->msg( 'scribunto-console-too-large' )->text(),
'scribunto-console-too-large'
);
}
$result = $this->runConsole( array(
'title' => $title,
'content' => $newSession['content'],
'prevQuestions' => $session['questions'],
'question' => $params['question'] ) );
if ( $result['type'] === 'error' ) {
// Restore the questions array
$newSession['questions'] = $session['questions'];
}
$cache->set( $sessionKey, $newSession, self::SC_SESSION_EXPIRY );
$result['session'] = $sessionId;
$result['sessionSize'] = $newSession['size'];
$result['sessionMaxSize'] = self::SC_MAX_SIZE;
if ( $sessionIsNew ) {
$result['sessionIsNew'] = '';
}
foreach ( $result as $key => $value ) {
$this->getResult()->addValue( null, $key, $value );
}
}
protected function runConsole( $params ) {
global $wgParser;
$options = new ParserOptions;
$wgParser->startExternalParse( $params['title'], $options, Parser::OT_HTML, true );
$engine = Scribunto::getParserEngine( $wgParser );
try {
$result = $engine->runConsole( $params );
} catch ( ScribuntoException $e ) {
$trace = $e->getScriptTraceHtml();
$message = $e->getMessage();
$html = Html::element( 'p', array(), $message );
if ( $trace !== false ) {
$html .= Html::element( 'p',
array(),
$this->msg( 'scribunto-common-backtrace' )->inContentLanguage()->text()
) . $trace;
}
return array(
'type' => 'error',
'html' => $html,
'message' => $message,
'messagename' => $e->getMessageName() );
}
return array(
'type' => 'normal',
'print' => strval( $result['print'] ),
'return' => strval( $result['return'] )
);
}
protected function newSession() {
return array(
'content' => '',
'questions' => array(),
'size' => 0,
'version' => 1,
);
}
public function isInternal() {
return true;
}
public function getAllowedParams() {
return array(
'title' => array(
ApiBase::PARAM_TYPE => 'string',
),
'content' => array(
ApiBase::PARAM_TYPE => 'string'
),
'session' => array(
ApiBase::PARAM_TYPE => 'integer',
),
'question' => array(
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_REQUIRED => true,
),
'clear' => array(
ApiBase::PARAM_TYPE => 'boolean',
),
);
}
/**
* @deprecated since MediaWiki core 1.25
*/
public function getParamDescription() {
return array(
'title' => 'The module title to test',
'content' => 'The new content of the module',
'question' => 'The next line to evaluate as a script',
'clear' => 'Set this to true to clear the current session state',
);
}
/**
* @deprecated since MediaWiki core 1.25
*/
public function getDescription() {
return 'Internal module for servicing XHR requests from the Scribunto console';
}
}