From c3fcaba02f7fbc4af288f716f630f6cbf0389221 Mon Sep 17 00:00:00 2001 From: =?utf8?q?E=CC=81tienne=20Beaule=CC=81?= Date: Sat, 12 Jul 2014 21:36:37 -0400 Subject: [PATCH] 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 --- RELEASE-NOTES-1.24 | 1 + includes/EditPage.php | 27 ++++++++++++++----- includes/api/ApiEditPage.php | 3 ++- includes/content/ContentHandler.php | 5 ++++ languages/i18n/en.json | 2 ++ languages/i18n/qqq.json | 2 ++ tests/phpunit/includes/EditPageTest.php | 13 +++++++++ .../phpunit/includes/api/ApiEditPageTest.php | 8 ------ 8 files changed, 46 insertions(+), 15 deletions(-) diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24 index cd24ef0bb0..fa24dadeec 100644 --- a/RELEASE-NOTES-1.24 +++ b/RELEASE-NOTES-1.24 @@ -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 diff --git a/includes/EditPage.php b/includes/EditPage.php index 5864c9b5bf..50225ccc65 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -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( "
\n$1\n
", 'missingcommentheader' ); } + if ( $this->blankArticle ) { + $wgOut->wrapWikiMsg( "
\n$1\n
", 'blankarticle' ); + } + if ( $this->hookError !== '' ) { $wgOut->addWikiText( $this->hookError ); } diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php index 884306a299..8a0c28081e 100644 --- a/includes/api/ApiEditPage.php +++ b/includes/api/ApiEditPage.php @@ -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'] ) ) { diff --git a/includes/content/ContentHandler.php b/includes/content/ContentHandler.php index 6be06c6094..1d7a7a7a9e 100644 --- a/includes/content/ContentHandler.php +++ b/includes/content/ContentHandler.php @@ -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 ''; diff --git a/languages/i18n/en.json b/languages/i18n/en.json index e235ad0d4c..fa0d758aaa 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -582,6 +582,7 @@ "preview": "Preview", "showpreview": "Show preview", "showdiff": "Show changes", + "blankarticle": "Warning: The page you are creating is blank.\nIf you click \"{{int:savearticle}}\" again, the page will be created without any content.", "anoneditwarning": "Warning: You are not logged in.\nYour IP address will be recorded in this page's edit history.", "anonpreviewwarning": "You are not logged in. Saving will record your IP address in this page's edit history.", "missingsummary": "Reminder: 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", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index ea6a839c0a..b221ee57db 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -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).", diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php index 28c35b3697..6537364994 100644 --- a/tests/phpunit/includes/EditPageTest.php +++ b/tests/phpunit/includes/EditPageTest.php @@ -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() { diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php index 9f8c13994e..3179a45228 100644 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ b/tests/phpunit/includes/api/ApiEditPageTest.php @@ -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, -- 2.20.1