Enable the creation of empty pages

This change enables the direct creation of empty pages without needing
to use a work-around (such as "{{subst:ns:0}}"). A warning is added as
the message "blankarticle" to request confirmation that the empty page
was meant to be blank. A automatic edit summary has been added when
creating a blank page. The message is: "autosumm-newblank."

The API has been updated to permit the creation of empty pages, when
"text" is null, but not non-existant.

Unit tests have also been added to test these features.

Bug: 57238
Bug: 65206
Change-Id: I3457c36a909d1dbfaeed04a1f0568c69e0ef3386
This commit is contained in:
Étienne Beaulé 2014-07-12 21:36:37 -04:00
parent 1137960eea
commit c3fcaba02f
8 changed files with 46 additions and 15 deletions

View file

@ -161,6 +161,7 @@ production.
wrong constraints.
* (bug 67870) wfShellExec() cuts off stdout at multiples of 8192 bytes.
* $wgRunJobsAsync now works with private wikis (e.g. read requires login).
* (bugs 57238, 65206) Blank pages can now be directly created.
=== Web API changes in 1.24 ===
* action=parse API now supports prop=modules, which provides the list of

View file

@ -99,7 +99,7 @@ class EditPage {
const AS_NO_CREATE_PERMISSION = 223;
/**
* Status: user tried to create a blank page
* Status: user tried to create a blank page and wpIgnoreBlankArticle == false
*/
const AS_BLANK_ARTICLE = 224;
@ -244,6 +244,12 @@ class EditPage {
/** @var bool */
protected $allowBlankSummary = false;
/** @var bool */
protected $blankArticle = false;
/** @var bool */
protected $allowBlankArticle = false;
/** @var string */
protected $autoSumm = '';
@ -850,6 +856,8 @@ class EditPage {
}
$this->autoSumm = $request->getText( 'wpAutoSummary' );
$this->allowBlankArticle = $request->getBool( 'wpIgnoreBlankArticle' );
} else {
# Not a posted form? Start with nothing.
wfDebug( __METHOD__ . ": Not a posted form.\n" );
@ -1390,6 +1398,7 @@ class EditPage {
case self::AS_TEXTBOX_EMPTY:
case self::AS_MAX_ARTICLE_SIZE_EXCEEDED:
case self::AS_END:
case self::AS_BLANK_ARTICLE:
return true;
case self::AS_HOOK_ERROR:
@ -1425,10 +1434,6 @@ class EditPage {
$wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
return false;
case self::AS_BLANK_ARTICLE:
$wgOut->redirect( $this->getContextTitle()->getFullURL() );
return false;
case self::AS_SPAM_ERROR:
$this->spamPageWithContent( $resultDetails['spam'] );
return false;
@ -1767,7 +1772,9 @@ class EditPage {
$defaultText = '';
}
if ( $this->textbox1 === $defaultText ) {
if ( !$this->allowBlankArticle && $this->textbox1 === $defaultText ) {
$this->blankArticle = true;
$status->fatal( 'blankarticle' );
$status->setResult( false, self::AS_BLANK_ARTICLE );
wfProfileOut( __METHOD__ );
return $status;
@ -2521,6 +2528,10 @@ class EditPage {
$wgOut->addHTML( EditPage::getEditToolbar() );
}
if ( $this->blankArticle ) {
$wgOut->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
}
if ( $this->isConflict ) {
// In an edit conflict bypass the overridable content form method
// and fallback to the raw wpTextbox1 since editconflicts can't be
@ -2649,6 +2660,10 @@ class EditPage {
$wgOut->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
}
if ( $this->blankArticle ) {
$wgOut->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
}
if ( $this->hookError !== '' ) {
$wgOut->addWikiText( $this->hookError );
}

View file

@ -252,7 +252,8 @@ class ApiEditPage extends ApiBase {
'format' => $contentFormat,
'model' => $contentHandler->getModelID(),
'wpEditToken' => $params['token'],
'wpIgnoreBlankSummary' => ''
'wpIgnoreBlankSummary' => '',
'wpIgnoreBlankArticle' => true
);
if ( !is_null( $params['summary'] ) ) {

View file

@ -821,6 +821,11 @@ abstract class ContentHandler {
->inContentLanguage()->text();
}
// New blank article auto-summary
if ( $flags && EDIT_NEW && $newContent->getSize() == 0 ) {
return wfMessage( 'autosumm-newblank' ) ->inContentLanguage()->text();
}
// If we reach this point, there's no applicable auto-summary for our
// case, so our auto-summary is empty.
return '';

View file

@ -582,6 +582,7 @@
"preview": "Preview",
"showpreview": "Show preview",
"showdiff": "Show changes",
"blankarticle": "<strong>Warning:</strong> The page you are creating is blank.\nIf you click \"{{int:savearticle}}\" again, the page will be created without any content.",
"anoneditwarning": "<strong>Warning:</strong> You are not logged in.\nYour IP address will be recorded in this page's edit history.",
"anonpreviewwarning": "<em>You are not logged in. Saving will record your IP address in this page's edit history.</em>",
"missingsummary": "<strong>Reminder:</strong> You have not provided an edit summary.\nIf you click \"{{int:savearticle}}\" again, your edit will be saved without one.",
@ -3113,6 +3114,7 @@
"autosumm-replace": "Replaced content with \"$1\"",
"autoredircomment": "Redirected page to [[$1]]",
"autosumm-new": "Created page with \"$1\"",
"autosumm-newblank": "Created blank page",
"autoblock_whitelist": "AOL http://webmaster.info.aol.com/proxyinfo.html\n*64.12.96.0/19\n*149.174.160.0/20\n*152.163.240.0/21\n*152.163.248.0/22\n*152.163.252.0/23\n*152.163.96.0/22\n*152.163.100.0/23\n*195.93.32.0/22\n*195.93.48.0/22\n*195.93.64.0/19\n*195.93.96.0/19\n*195.93.16.0/20\n*198.81.0.0/22\n*198.81.16.0/20\n*198.81.8.0/23\n*202.67.64.128/25\n*205.188.192.0/20\n*205.188.208.0/23\n*205.188.112.0/20\n*205.188.146.144/30\n*207.200.112.0/21",
"size-bytes": "$1 B",
"size-kilobytes": "$1 KB",

View file

@ -744,6 +744,7 @@
"preview": "The title of the Preview page shown after clicking the \"Show preview\" button in the edit page. Since this is a heading, it should probably be translated as a noun and not as a verb.\n\n{{Identical|Preview}}",
"showpreview": "The text of the button to preview the page you are editing. See also {{msg-mw|showdiff}} and {{msg-mw|savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}\n{{Identical|Show preview}}",
"showdiff": "Button below the edit page. See also {{msg-mw|Showpreview}} and {{msg-mw|Savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}\n{{Identical|Show change}}",
"blankarticle": "Notice displayed once after the user tries to save an empty page.",
"anoneditwarning": "Shown when editing a page anonymously.\nSee also:\n* {{msg-mw|Sf autoedit anoneditwarning}}\n* {{msg-mw|Wikibase-anonymouseditwarning-property}}\n* {{msg-mw|Wikibase-anonymouseditwarning-item}}\n* {{msg-mw|Anonpreviewwarning}}",
"anonpreviewwarning": "See also:\n* {{msg-mw|Anoneditwarning}}",
"missingsummary": "The text \"edit summary\" is in {{msg-mw|Summary}}.\n\nSee also:\n* {{msg-mw|Missingcommentheader}}\n* {{msg-mw|Savearticle}}",
@ -3275,6 +3276,7 @@
"autosumm-replace": "The auto summary when a user removes a lot of characters in the page.\n\nParameters:\n* $1 - truncated text",
"autoredircomment": "The auto summary when making a redirect. Parameters:\n* $1 - the page where it redirects to\n* $2 - (Optional) the first X number of characters of the redirect ($2 is usually only used when end users customize the message)",
"autosumm-new": "The auto summary when creating a new page. $1 are the first X number of characters of the new page.",
"autosumm-newblank": "The automatic edit summary when creating a blank page. This is not the same as blanking a page.",
"autoblock_whitelist": "{{notranslate}}",
"size-bytes": "{{optional}}\nSize (of a page, typically) in bytes.",
"size-kilobytes": "{{optional}}\nSize (of a page, typically) in kibibytes (1 kibibyte = 1024 bytes).",

View file

@ -265,6 +265,19 @@ class EditPageTest extends MediaWikiLangTestCase {
null,
"expected MediaWiki: page not being created if text equals default message"
);
$this->assertEdit(
'EditPageTest_testCreatePage',
null,
null,
array(
'wpTextbox1' => "",
'wpIgnoreBlankArticle' => 1,
),
EditPage::AS_SUCCESS_NEW_ARTICLE,
"",
"expected empty article being created"
)->doDeleteArticleReal( 'EditPageTest_testCreatePage' );
}
public function testUpdatePage() {

View file

@ -161,14 +161,6 @@ class ApiEditPageTest extends ApiTestCase {
// -- create page (or not) -----------------------------------------
if ( $text !== null ) {
if ( $text === '' ) {
// can't create an empty page, so create it with some content
$this->doApiRequestWithToken( array(
'action' => 'edit',
'title' => $name,
'text' => '(dummy)', ) );
}
list( $re ) = $this->doApiRequestWithToken( array(
'action' => 'edit',
'title' => $name,