mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-28 16:20:52 +00:00
Merge "api: Split save action into separate API module"
This commit is contained in:
commit
87f48b1d44
|
@ -101,46 +101,6 @@ class ApiVisualEditor extends ApiBase {
|
|||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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,
|
||||
true // was posted
|
||||
),
|
||||
true // enable write
|
||||
);
|
||||
|
||||
$api->execute();
|
||||
|
||||
return $api->getResultData();
|
||||
}
|
||||
|
||||
protected function parseWikitext( $title ) {
|
||||
$apiParams = array(
|
||||
'action' => 'parse',
|
||||
|
@ -318,52 +278,6 @@ class ApiVisualEditor extends ApiBase {
|
|||
$result = array( 'result' => 'success', 'content' => $content );
|
||||
}
|
||||
break;
|
||||
case 'save':
|
||||
$wikitext = $this->postHTML( $page, $params['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 ( !isset( $saveresult['edit']['result'] ) || $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' );
|
||||
}
|
||||
|
||||
if ( isset( $saveresult['edit']['newrevid'] ) ) {
|
||||
$result['newrevid'] = intval( $saveresult['edit']['newrevid'] );
|
||||
}
|
||||
|
||||
$result['result'] = 'success';
|
||||
}
|
||||
break;
|
||||
case 'diff':
|
||||
$wikitext = $this->postHTML( $page, $params['html'], $parserParams );
|
||||
|
||||
|
@ -390,33 +304,18 @@ class ApiVisualEditor extends ApiBase {
|
|||
),
|
||||
'paction' => array(
|
||||
ApiBase::PARAM_REQUIRED => true,
|
||||
ApiBase::PARAM_TYPE => array( 'parse', 'parsefragment', 'serialize', 'save', 'diff' ),
|
||||
),
|
||||
'token' => array(
|
||||
ApiBase::PARAM_REQUIRED => true,
|
||||
ApiBase::PARAM_TYPE => array( 'parse', 'parsefragment', 'serialize', 'diff' ),
|
||||
),
|
||||
'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,
|
||||
);
|
||||
}
|
||||
|
||||
public function needsToken() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTokenSalt() {
|
||||
return '';
|
||||
return false;
|
||||
}
|
||||
|
||||
public function mustBePosted() {
|
||||
|
@ -435,20 +334,12 @@ class ApiVisualEditor extends ApiBase {
|
|||
return array(
|
||||
'page' => 'The page to perform actions on.',
|
||||
'paction' => 'Action to perform',
|
||||
'oldid' => 'The revision number to use. For paction=save, defauls to latest revision.' +
|
||||
' Required for other actions. Use 0 for new page.',
|
||||
'minor' => 'Flag for minor edit.',
|
||||
'oldid' => 'The revision number to use (defaults to latest version).',
|
||||
'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).',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
182
ApiVisualEditorEdit.php
Normal file
182
ApiVisualEditorEdit.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
/**
|
||||
* Parsoid API wrapper.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
* @copyright 2011-2013 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;
|
||||
}
|
||||
|
||||
// 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,
|
||||
true // was posted
|
||||
),
|
||||
true // enable write
|
||||
);
|
||||
|
||||
$api->execute();
|
||||
|
||||
return $api->getResultData();
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
global $wgVisualEditorNamespaces, $wgVisualEditorUseChangeTagging,
|
||||
$wgVisualEditorEditNotices;
|
||||
$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'];
|
||||
}
|
||||
|
||||
$wikitext = $this->postHTML( $page, $params['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 ( !isset( $saveresult['edit']['result'] ) || $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' );
|
||||
}
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
public function needsToken() {
|
||||
return true;
|
||||
}
|
||||
|
||||
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).',
|
||||
);
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return 'Save an HTML5 page to MediaWiki (converted to wikitext via the Parsoid service).';
|
||||
}
|
||||
}
|
|
@ -732,7 +732,9 @@ $wgResourceModules += array(
|
|||
);
|
||||
// Parsoid Wrapper API
|
||||
$wgAutoloadClasses['ApiVisualEditor'] = $dir . 'ApiVisualEditor.php';
|
||||
$wgAutoloadClasses['ApiVisualEditorEdit'] = $dir . 'ApiVisualEditorEdit.php';
|
||||
$wgAPIModules['visualeditor'] = 'ApiVisualEditor';
|
||||
$wgAPIModules['visualeditoredit'] = 'ApiVisualEditorEdit';
|
||||
|
||||
// Integration Hooks
|
||||
$wgAutoloadClasses['VisualEditorHooks'] = $dir . 'VisualEditor.hooks.php';
|
||||
|
|
|
@ -459,7 +459,7 @@ ve.init.mw.ViewPageTarget.prototype.onSaveError = function ( jqXHR, status, data
|
|||
// "question" or "fancy" type of captcha. They all expose differently named properties in the
|
||||
// API for different things in the UI. At this point we only support the FancyCaptha which we
|
||||
// very intuitively detect by the presence of a "url" property.
|
||||
editApi = data && data.visualeditor && data.visualeditor.edit;
|
||||
editApi = data && data.visualeditoredit && data.visualeditoredit.edit;
|
||||
if ( editApi && editApi.captcha && editApi.captcha.url ) {
|
||||
this.captcha = {
|
||||
input: new ve.ui.TextInputWidget(),
|
||||
|
|
|
@ -314,7 +314,7 @@ ve.init.mw.Target.onTokenError = function ( jqXHR, status, error ) {
|
|||
*/
|
||||
ve.init.mw.Target.onSave = function ( response ) {
|
||||
this.saving = false;
|
||||
var data = response.visualeditor;
|
||||
var data = response.visualeditoredit;
|
||||
if ( !data && !response.error ) {
|
||||
ve.init.mw.Target.onSaveError.call( this, null, 'Invalid response from server', response );
|
||||
} else if ( response.error ) {
|
||||
|
@ -506,7 +506,6 @@ ve.init.mw.Target.prototype.load = function () {
|
|||
'action': 'visualeditor',
|
||||
'paction': 'parse',
|
||||
'page': this.pageName,
|
||||
'token': this.editToken,
|
||||
'format': 'json'
|
||||
};
|
||||
|
||||
|
@ -574,8 +573,7 @@ ve.init.mw.Target.prototype.save = function ( doc, options ) {
|
|||
|
||||
var data = {
|
||||
'format': 'json',
|
||||
'action': 'visualeditor',
|
||||
'paction': 'save',
|
||||
'action': 'visualeditoredit',
|
||||
'page': this.pageName,
|
||||
'oldid': this.revid,
|
||||
'basetimestamp': this.baseTimeStamp,
|
||||
|
@ -631,9 +629,7 @@ ve.init.mw.Target.prototype.showChanges = function ( doc ) {
|
|||
'paction': 'diff',
|
||||
'page': this.pageName,
|
||||
'oldid': this.revid,
|
||||
'html': this.getHtml( doc ),
|
||||
// TODO: API required editToken, though not relevant for diff
|
||||
'token': this.editToken
|
||||
'html': this.getHtml( doc )
|
||||
},
|
||||
'dataType': 'json',
|
||||
'type': 'POST',
|
||||
|
@ -722,7 +718,6 @@ ve.init.mw.Target.prototype.serialize = function ( doc, callback ) {
|
|||
'html': this.getHtml( doc ),
|
||||
'page': this.pageName,
|
||||
'oldid': this.revid,
|
||||
'token': this.editToken,
|
||||
'format': 'json'
|
||||
},
|
||||
'dataType': 'json',
|
||||
|
|
Loading…
Reference in a new issue