jenkins-bot has submitted this change and it was merged.
Change subject: Add NewsletterValidator and changes to Special:CreateNewsletter
......................................................................
Add NewsletterValidator and changes to Special:CreateNewsletter
Add a new class NewsletterValidator which can also be used when
newsletter fields are edited.
Changes to Special:CreateNewsletter
- Separate error messages shown for main page and newsletter name key collisions
- Rename autoSubscribe() to onPostCreation() as it doesn't only do subscription
- Use Title's naming restrictions for newsletter names as well
- Don't rely on the web form's browser validation as this can easily be bypassed
- Don't allow whitespace characters on required input
- Increase newsletter name maxlength's field - currently it's a bit low
Bug: T110491
Change-Id: Ica686bc1eb26bb482c07dff9e0982bbcdad3b210
---
M extension.json
M i18n/en.json
M i18n/qqq.json
A includes/NewsletterValidator.php
M includes/specials/SpecialNewsletterCreate.php
5 files changed, 135 insertions(+), 56 deletions(-)
Approvals:
01tonythomas: Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index 88b3245..b90ba12 100644
--- a/extension.json
+++ b/extension.json
@@ -50,6 +50,7 @@
"Newsletter": "includes/Newsletter.php",
"NewsletterDb": "includes/NewsletterDb.php",
"NewsletterHooks": "Newsletter.hooks.php",
+ "NewsletterValidator": "includes/NewsletterValidator.php",
"NewsletterLinksGenerator":
"includes/specials/NewsletterLinksGenerator.php",
"SpecialNewsletter": "includes/specials/SpecialNewsletter.php",
"SpecialNewsletters":
"includes/specials/SpecialNewsletters.php",
diff --git a/i18n/en.json b/i18n/en.json
index 9c4bd79..88c1ad1 100755
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -10,12 +10,17 @@
"newsletter-name": "Name of newsletter",
"newsletter-desc": "Description",
"newsletter-title": "Title of Main Page",
- "newsletter-exist-error": "A newsletter with the same name already
exists. Try again with another name",
+ "newsletter-exist-error": "A newsletter with the name \"$1\" already
exists. Please try again with another name.",
+ "newsletter-create-error": "An error occured while trying to create a
new newsletter. Please try again.",
+ "newsletter-input-required": "Required input was not entered. Please
try again.",
+ "newsletter-invalid-name": "The name you entered for the newsletter is
invalid. Please try again.",
"newslettercreate": "Create newsletter",
"newslettercreate-text": "This page allows you to create a new
newsletter. You will be added as a publisher and subscribed to the newsletter
on its creation. All fields are required.",
"newsletter-create-submit": "Create newsletter",
"newsletter-create-confirmation": "A new newsletter has been
successfully created.",
"newsletter-create-mainpage-error": "Invalid newsletter main page
entered. Please try again.",
+ "newsletter-mainpage-non-existent": "The newsletter main page does not
exist. Please enter a valid existing page.",
+ "newsletter-mainpage-in-use": "An existing newsletter has the same main
page. Please enter another title.",
"newsletter-create-short-description-error": "The description is too
short (less than 30 characters). Please try again.",
"newsletter-subtitlelinks-list": "List of newsletters",
"newsletter-subtitlelinks-create": "Create a new newsletter",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 99c2b63..d77be7f 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -14,11 +14,16 @@
"newsletter-name": "Label of the field which takes the name of
newsletter as input in [[Special:CreateNewsletter]]",
"newsletter-desc": "Label of the field which takes a short description
of newsletter as input in
[[Special:CreateNewsletter]]\n{{Identical|Description}}",
"newsletter-title": "Label of the field which takes the title of Main
Page of newsletter as input in [[Special:CreateNewsletter]]",
- "newsletter-exist-error": "Error message to be displayed in
[[Special:CreateNewsletter]] when trying to create a newsletter with same name
as an existing newsletter",
+ "newsletter-exist-error": "Error message to be displayed in
[[Special:CreateNewsletter]] when trying to create a newsletter with same name
as an existing newsletter. $1- Name of newsletter",
+ "newsletter-create-error": "Error message shown on
[[Special:CreateNewsletter]] if newsletter creation failed.",
+ "newsletter-input-required": "Error message shown on
[[Special:CreateNewsletter]] if required input is missing..",
+ "newsletter-invalid-name": "Error message shown on
[[Special:CreateNewsletter]] if the newsletter name is invalid.",
"newslettercreate": "Name of [[Special:CreateNewsletter]]. This is used
as the header on this page and shown in links to the page.",
"newslettercreate-text": "Introductory message shown on top of
Special:CreateNewsletter.",
"newsletter-create-submit": "Label of submit button on
[[Special:CreateNewsletter]]",
"newsletter-create-confirmation": "Confirmation message displayed after
creation of a newsletter",
+ "newsletter-mainpage-non-existent": "Error message shown if the
newsletter main page doesn't exist.",
+ "newsletter-mainpage-in-use": "Error message shown if the newsletter's
main page is already in use by another newsletter.",
"newsletter-create-mainpage-error": "Error message shown on
[[Special:CreateNewsletter]] if the page entered on main page field does not
exist.",
"newsletter-create-short-description-error": "Error message shown on
[[Special:CreateNewsletter]] if the text entered in the description field is
too short.",
"newsletter-subtitlelinks-list": "Label for link to
[[Special:Newsletters]] shown under the header on Newsletter special
pages.\n\nSee also:\n* {{msg-mw|newsletter-subtitlelinks-create}}",
diff --git a/includes/NewsletterValidator.php b/includes/NewsletterValidator.php
new file mode 100644
index 0000000..1837d88
--- /dev/null
+++ b/includes/NewsletterValidator.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Handles validation for newsletters
+ */
+
+class NewsletterValidator {
+
+ private static $requiredData = array(
+ 'Name',
+ 'Description',
+ 'MainPage',
+ );
+
+ public function __construct( $fields ) {
+ $this->data = $fields;
+ }
+
+ /**
+ * Check whether all input have proper values
+ *
+ * @return Status fatal if invalid, good otherwise
+ */
+ public function validate() {
+ // Check whether required fields are not empty
+ foreach( self::$requiredData as $field ) {
+ if ( trim( $this->data[ $field ] ) === '' ) {
+ return Status::newFatal(
'newsletter-input-required' );
+ }
+ }
+
+ // Prevents random nonsensical characters in newsletter names
+ // and also adds a length limit
+ // (uses Title's rules now - maybe use our own?)
+ $name = Title::makeTitleSafe( NS_MAIN, $this->data['Name'] );
+ if ( !$name ) {
+ return Status::newFatal( 'newsletter-invalid-name' );
+ }
+
+ if ( strlen ( $this->data['Description'] ) < 30 ) {
+ // Should this limit be lowered?
+ return Status::newFatal(
'newsletter-create-short-description-error' );
+ }
+
+ $mainTitle = $this->data['MainPage'];
+ if ( !$mainTitle ) {
+ return Status::newFatal(
'newsletter-create-mainpage-error' );
+ }
+
+ if ( !$mainTitle->canExist() ) {
+ return Status::newFatal(
'newsletter-create-mainpage-error' );
+ }
+
+ if ( !$mainTitle->exists() ) {
+ return Status::newFatal(
'newsletter-mainpage-non-existent' );
+ }
+
+
+
+ return Status::newGood();
+ }
+}
diff --git a/includes/specials/SpecialNewsletterCreate.php
b/includes/specials/SpecialNewsletterCreate.php
index bfb0848..fe8521f 100644
--- a/includes/specials/SpecialNewsletterCreate.php
+++ b/includes/specials/SpecialNewsletterCreate.php
@@ -36,7 +36,7 @@
'type' => 'text',
'required' => true,
'label-message' => 'newsletter-name',
- 'maxlength' => 50
+ 'maxlength' => 120
),
'description' => array(
'type' => 'textarea',
@@ -47,7 +47,6 @@
),
'mainpage' => array(
'type' => 'title',
- 'exists' => true,
'required' => true,
'label-message' => 'newsletter-title',
),
@@ -57,17 +56,47 @@
/**
* Do input validation, error handling and create a new newletter.
*
- * @param array $data The data entered by user in the form
- * @return bool|array true on success, array on error
+ * @param array $input The data entered by user in the form
+ * @throws ThrottledError
+ * @return Status
*/
- public function onSubmit( array $data ) {
+ public function onSubmit( array $input ) {
global $wgContLang;
- $mainTitle = Title::newFromText( $data['mainpage'] );
- if ( !$mainTitle ) {
- // HTMLTitleTextField should do validation but we can't
be sure about
- // it so let's check again here - otherwise this may
throw fatals below
- return array( 'newsletter-create-mainpage-error' );
+ $data = array(
+ 'Name' => trim( $input['name'] ),
+ 'Description' => trim( $input['description'] ),
+ 'MainPage' => Title::newFromText( $input['mainpage'] ),
+ );
+
+ $validator = new NewsletterValidator( $data );
+ $validation = $validator->validate();
+ if ( !$validation->isGood() ) {
+ // Invalid input was entered
+ return $validation;
+ }
+
+ $mainPageId = $data['MainPage']->getArticleID();
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $rows = $dbr->select(
+ 'nl_newsletters',
+ array( 'nl_name', 'nl_main_page_id' ),
+ $dbr->makeList(
+ array(
+ 'nl_name' => $data['Name'],
+ 'nl_main_page_id' => $mainPageId,
+ ),
+ LIST_OR
+ )
+ );
+ // Check whether another existing newsletter has the same name
or main page
+ foreach( $rows as $row ) {
+ if ( $row->nl_name === $data['Name'] ) {
+ return Status::newFatal(
'newsletter-exist-error', $data['Name'] );
+ } elseif ( (int)$row->nl_main_page_id === $mainPageId )
{
+ return Status::newFatal(
'newsletter-mainpage-in-use' );
+ }
}
$user = $this->getUser();
@@ -77,55 +106,25 @@
throw new ThrottledError;
}
- $articleId = $mainTitle->getArticleId();
-
- if ( isset( $data['name'] ) &&
- isset( $data['description'] ) &&
- ( $articleId !== 0 ) &&
- isset( $data['mainpage'] )
- ) {
- if ( strlen ( $data['description'] ) < 30 ) {
- return array(
'newsletter-create-short-description-error' );
- }
-
- $db = NewsletterDb::newFromGlobalState();
-
+ $ndb = NewsletterDb::newFromGlobalState();
+ $newsletterCreated = $ndb->addNewsletter(
+ $data['Name'],
// nl_newsletters.nl_desc is a blob but put some limit
- // here which is less than max size for blobs
- $description = $wgContLang->truncate( trim(
$data['description'] ), 600000 );
+ // here which is less than the max size for blobs
+ $wgContLang->truncate( $data['Description'], 600000 ),
+ $mainPageId
+ );
- $newsletterAdded = $db->addNewsletter(
- trim( $data['name'] ),
- $description,
- $articleId
- );
+ if ( $newsletterCreated ) {
+ $newsletter = $ndb->getNewsletterForPageId( $mainPageId
);
+ $this->onPostCreation( $newsletter->getId(),
$user->getId() );
- if ( !$newsletterAdded ) {
- // @todo FIXME: This shouldn't be thrown for
main page key collisions
- return array( 'newsletter-exist-error' );
- }
-
- $newsletter = $db->getNewsletterForPageId( $articleId );
-
- $this->autoSubscribe( $newsletter->getId(),
$user->getId() );
-
- return true;
+ return Status::newGood();
}
- // Could not insert - newsletter by this name already exists
- return array( 'newsletter-exist-error' );
-
+ // Couldn't insert to the DB..
+ return Status::newFatal( 'newsletter-create-error' );
}
-
- protected function getDisplayFormat() {
- return 'ooui';
- }
-
- public function onSuccess() {
- // @todo Link to corresponding Special:Newsletter page
- $this->getOutput()->addWikiMsg(
'newsletter-create-confirmation' );
- }
-
/**
* Automatically subscribe and add creator as publisher of the
newsletter
@@ -133,10 +132,18 @@
* @param int $newsletterId Id of the newsletter
* @param int $userID User Id of the publisher
*/
- private function autoSubscribe( $newsletterId, $userID ) {
+ private function onPostCreation( $newsletterId, $userID ) {
$db = NewsletterDb::newFromGlobalState();
$db->addPublisher( $userID, $newsletterId );
$db->addSubscription( $userID, $newsletterId );
}
+ public function onSuccess() {
+ // @todo Link to corresponding Special:Newsletter page
+ $this->getOutput()->addWikiMsg(
'newsletter-create-confirmation' );
+ }
+
+ protected function getDisplayFormat() {
+ return 'ooui';
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/270496
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ica686bc1eb26bb482c07dff9e0982bbcdad3b210
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/Newsletter
Gerrit-Branch: master
Gerrit-Owner: Glaisher <[email protected]>
Gerrit-Reviewer: 01tonythomas <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits