mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-01 17:36:35 +00:00
6dd98b5f3b
MediaWiki change I2793a3f2 changes API handling in a way that needs updates to extensions for proper operation: * needsToken() now returns a string * Most custom token types are being replaced with a 'csrf' token (the former 'edit' token); any others need a new hook. * All tokens must use a static salt. Compat with web UI using non-static tokens is supported and also serves to handle the now-deprecated token fetching. * Documentation in getParamDescription() should return a string (not array) for 'token', as the signal to core that it should be replaced with a standardized message. When compatibility with earlier versions of MediaWiki is no longer maintained, the entry for 'token' from getAllowedParams() and getParamDescription() may be removed, as may getTokenSalt(). This patch leaves them in place. Note this is intended to be compatible with earlier versions of MediaWiki, and so should be safe to merge before the core change. Change-Id: Ia6e512aae366996de4e73a8d7f4f03fcddd77286
208 lines
5.7 KiB
PHP
208 lines
5.7 KiB
PHP
<?php
|
|
/**
|
|
* Parsoid API wrapper.
|
|
*
|
|
* @file
|
|
* @ingroup Extensions
|
|
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
class ApiVisualEditorEdit extends ApiVisualEditor {
|
|
|
|
protected function saveWikitext( $title, $wikitext, $params ) {
|
|
$apiParams = array(
|
|
'action' => 'edit',
|
|
'title' => $title->getPrefixedDBkey(),
|
|
'text' => $wikitext,
|
|
'summary' => $params['summary'],
|
|
'basetimestamp' => $params['basetimestamp'],
|
|
'starttimestamp' => $params['starttimestamp'],
|
|
'token' => $params['token'],
|
|
);
|
|
|
|
if ( $params['minor'] ) {
|
|
$apiParams['minor'] = true;
|
|
} else {
|
|
$apiParams['notminor'] = true;
|
|
}
|
|
|
|
// FIXME add some way that the user's preferences can be respected
|
|
$apiParams['watchlist'] = $params['watch'] ? 'watch' : 'unwatch';
|
|
|
|
if ( $params['captchaid'] ) {
|
|
$apiParams['captchaid'] = $params['captchaid'];
|
|
}
|
|
|
|
if ( $params['captchaword'] ) {
|
|
$apiParams['captchaword'] = $params['captchaword'];
|
|
}
|
|
|
|
$api = new ApiMain(
|
|
new DerivativeRequest(
|
|
$this->getRequest(),
|
|
$apiParams + $this->getRequest()->getValues(),
|
|
true // was posted
|
|
),
|
|
true // enable write
|
|
);
|
|
|
|
$api->execute();
|
|
|
|
return $api->getResultData();
|
|
}
|
|
|
|
public function execute() {
|
|
global $wgVisualEditorNamespaces, $wgVisualEditorUseChangeTagging;
|
|
|
|
$user = $this->getUser();
|
|
$params = $this->extractRequestParams();
|
|
$page = Title::newFromText( $params['page'] );
|
|
if ( !$page ) {
|
|
$this->dieUsageMsg( 'invalidtitle', $params['page'] );
|
|
}
|
|
if ( !in_array( $page->getNamespace(), $wgVisualEditorNamespaces ) ) {
|
|
$this->dieUsage( "VisualEditor is not enabled in namespace " .
|
|
$page->getNamespace(), 'novenamespace' );
|
|
}
|
|
|
|
$parserParams = array();
|
|
if ( isset( $params['oldid'] ) ) {
|
|
$parserParams['oldid'] = $params['oldid'];
|
|
}
|
|
|
|
$html = $params['html'];
|
|
if ( substr( $html, 0, 11 ) === 'rawdeflate,' ) {
|
|
$html = gzinflate( base64_decode( substr( $html, 11 ) ) );
|
|
}
|
|
|
|
if ( $params['cachekey'] !== null ) {
|
|
$wikitext = $this->trySerializationCache( $params['cachekey'] );
|
|
if ( !is_string( $wikitext ) ) {
|
|
$this->dieUsage( 'No cached serialization found with that key', 'badcachekey' );
|
|
}
|
|
} else {
|
|
$wikitext = $this->postHTML( $page, $html, $parserParams );
|
|
if ( $wikitext === false ) {
|
|
$this->dieUsage( 'Error contacting the Parsoid server', 'parsoidserver' );
|
|
}
|
|
}
|
|
|
|
$saveresult = $this->saveWikitext( $page, $wikitext, $params );
|
|
$editStatus = $saveresult['edit']['result'];
|
|
|
|
// Error
|
|
if ( $editStatus !== 'Success' ) {
|
|
$result = array(
|
|
'result' => 'error',
|
|
'edit' => $saveresult['edit']
|
|
);
|
|
|
|
// Success
|
|
} else {
|
|
if ( isset( $saveresult['edit']['newrevid'] ) && $wgVisualEditorUseChangeTagging ) {
|
|
ChangeTags::addTags( 'visualeditor', null,
|
|
intval( $saveresult['edit']['newrevid'] ),
|
|
null
|
|
);
|
|
if ( $params['needcheck'] ) {
|
|
ChangeTags::addTags( 'visualeditor-needcheck', null,
|
|
intval( $saveresult['edit']['newrevid'] ),
|
|
null
|
|
);
|
|
}
|
|
}
|
|
|
|
// Return result of parseWikitext instead of saveWikitext so that the
|
|
// frontend can update the page rendering without a refresh.
|
|
$result = $this->parseWikitext( $page );
|
|
if ( $result === false ) {
|
|
$this->dieUsage( 'Error contacting the Parsoid server', 'parsoidserver' );
|
|
}
|
|
$result['isRedirect'] = $page->isRedirect();
|
|
|
|
$content = new WikitextContent( $wikitext );
|
|
$parserOutput = $content->getParserOutput( $page );
|
|
if ( $parserOutput ) {
|
|
$result['displayTitleHtml'] = $parserOutput->getDisplayTitle();
|
|
} else {
|
|
wfDebug( '[VE] ApiVisualEditorEdit - parserOutput was false' );
|
|
}
|
|
|
|
if ( isset( $saveresult['edit']['newrevid'] ) ) {
|
|
$result['newrevid'] = intval( $saveresult['edit']['newrevid'] );
|
|
}
|
|
|
|
$result['result'] = 'success';
|
|
}
|
|
|
|
$this->getResult()->addValue( null, $this->getModuleName(), $result );
|
|
}
|
|
|
|
public function getAllowedParams() {
|
|
return array(
|
|
'page' => array(
|
|
ApiBase::PARAM_REQUIRED => true,
|
|
),
|
|
'token' => array(
|
|
ApiBase::PARAM_REQUIRED => true,
|
|
),
|
|
'wikitext' => null,
|
|
'basetimestamp' => null,
|
|
'starttimestamp' => null,
|
|
'needcheck' => array(
|
|
ApiBase::PARAM_TYPE => 'boolean'
|
|
),
|
|
'oldid' => null,
|
|
'minor' => null,
|
|
'watch' => null,
|
|
'html' => null,
|
|
'summary' => null,
|
|
'captchaid' => null,
|
|
'captchaword' => null,
|
|
'cachekey' => null,
|
|
);
|
|
}
|
|
|
|
public function needsToken() {
|
|
return 'csrf';
|
|
}
|
|
|
|
public function getTokenSalt() {
|
|
return '';
|
|
}
|
|
|
|
public function mustBePosted() {
|
|
return true;
|
|
}
|
|
|
|
public function isWriteMode() {
|
|
return true;
|
|
}
|
|
|
|
public function getParamDescription() {
|
|
return array(
|
|
'page' => 'The page to perform actions on.',
|
|
'oldid' => 'The revision number to use. Defaults to latest revision. Use 0 for new page.',
|
|
'minor' => 'Flag for minor edit.',
|
|
'html' => 'HTML to send to Parsoid in exchange for wikitext',
|
|
'summary' => 'Edit summary',
|
|
'basetimestamp' => 'When saving, set this to the timestamp of the revision that was'
|
|
. ' edited. Used to detect edit conflicts.',
|
|
'starttimestamp' => 'When saving, set this to the timestamp of when the page was loaded.'
|
|
. ' Used to detect edit conflicts.',
|
|
'token' => 'Edit token',
|
|
'needcheck' => 'When saving, set this parameter if the revision might have roundtrip'
|
|
. ' problems. This will result in the edit being tagged.',
|
|
'captchaid' => 'Captcha ID (when saving with a captcha response).',
|
|
'captchaword' => 'Answer to the captcha (when saving with a captcha response).',
|
|
'cachekey' => 'Use the result of a previous serializeforcache request with this key.'
|
|
. 'Overrides html.',
|
|
);
|
|
}
|
|
|
|
public function getDescription() {
|
|
return 'Save an HTML5 page to MediaWiki (converted to wikitext via the Parsoid service).';
|
|
}
|
|
}
|