Merge "Add support for extentions to change Special:Mute form"
authorDbarratt <dbarratt@wikimedia.org>
Thu, 18 Jul 2019 15:39:09 +0000 (15:39 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Jul 2019 15:39:09 +0000 (15:39 +0000)
RELEASE-NOTES-1.34
docs/hooks.txt
includes/specials/SpecialMute.php
languages/i18n/en.json
languages/i18n/qqq.json
tests/phpunit/includes/specials/SpecialMuteTest.php

index a92b5c2..99ede17 100644 (file)
@@ -77,6 +77,8 @@ For notes on 1.33.x and older releases, see HISTORY.
   of headers in private wikis.
 * Language::formatTimePeriod now supports the new 'avoidhours' option to output
   strings like "5 days ago" instead of "5 days 13 hours ago".
+* (T220163) Added SpecialMuteModifyFormFields hook to allow extensions
+  to add fields to Special:Mute.
 
 === External library changes in 1.34 ===
 
index 36e0891..756ba4e 100644 (file)
@@ -3200,6 +3200,10 @@ $request: WebRequest object for getting the value provided by the current user
 &$oldTitle: old title (object)
 &$newTitle: new title (object)
 
+'SpecialMuteModifyFormFields': Add more fields to Special:Mute
+$sp: SpecialPage object, for context
+&$fields: Current HTMLForm fields descriptors
+
 'SpecialNewpagesConditions': Called when building sql query for
 Special:NewPages.
 &$special: NewPagesPager object (subclass of ReverseChronologicalPager)
index 4f34785..f3ae31a 100644 (file)
@@ -28,6 +28,8 @@ use MediaWiki\Preferences\MultiUsernameFilter;
  */
 class SpecialMute extends FormSpecialPage {
 
+       const PAGE_NAME = 'Mute';
+
        /** @var User */
        private $target;
 
@@ -51,7 +53,7 @@ class SpecialMute extends FormSpecialPage {
 
                $this->centralIdLookup = CentralIdLookup::factory();
 
-               parent::__construct( 'Mute', '', false );
+               parent::__construct( self::PAGE_NAME, '', false );
        }
 
        /**
@@ -66,7 +68,7 @@ class SpecialMute extends FormSpecialPage {
                parent::execute( $par );
 
                $out = $this->getOutput();
-               $out->addModules( 'mediawiki.special.pageLanguage' );
+               $out->addModules( 'mediawiki.misc-authed-ooui' );
        }
 
        /**
@@ -97,10 +99,12 @@ class SpecialMute extends FormSpecialPage {
         * @return bool
         */
        public function onSubmit( array $data, HTMLForm $form = null ) {
-               if ( !empty( $data['MuteEmail'] ) ) {
-                       $this->muteEmailsFromTarget();
-               } else {
-                       $this->unmuteEmailsFromTarget();
+               foreach ( $data as $userOption => $value ) {
+                       if ( $value ) {
+                               $this->muteTarget( $userOption );
+                       } else {
+                               $this->unmuteTarget( $userOption );
+                       }
                }
 
                return true;
@@ -114,10 +118,12 @@ class SpecialMute extends FormSpecialPage {
        }
 
        /**
-        * Un-mute emails from target
+        * Un-mute target
+        *
+        * @param string $userOption up_property key that holds the blacklist
         */
-       private function unmuteEmailsFromTarget() {
-               $blacklist = $this->getBlacklist();
+       private function unmuteTarget( $userOption ) {
+               $blacklist = $this->getBlacklist( $userOption );
 
                $key = array_search( $this->targetCentralId, $blacklist );
                if ( $key !== false ) {
@@ -125,24 +131,25 @@ class SpecialMute extends FormSpecialPage {
                        $blacklist = implode( "\n", $blacklist );
 
                        $user = $this->getUser();
-                       $user->setOption( 'email-blacklist', $blacklist );
+                       $user->setOption( $userOption, $blacklist );
                        $user->saveSettings();
                }
        }
 
        /**
-        * Mute emails from target
+        * Mute target
+        * @param string $userOption up_property key that holds the blacklist
         */
-       private function muteEmailsFromTarget() {
+       private function muteTarget( $userOption ) {
                // avoid duplicates just in case
-               if ( !$this->isTargetBlacklisted() ) {
-                       $blacklist = $this->getBlacklist();
+               if ( !$this->isTargetBlacklisted( $userOption ) ) {
+                       $blacklist = $this->getBlacklist( $userOption );
 
                        $blacklist[] = $this->targetCentralId;
                        $blacklist = implode( "\n", $blacklist );
 
                        $user = $this->getUser();
-                       $user->setOption( 'email-blacklist', $blacklist );
+                       $user->setOption( $userOption, $blacklist );
                        $user->saveSettings();
                }
        }
@@ -150,30 +157,38 @@ class SpecialMute extends FormSpecialPage {
        /**
         * @inheritDoc
         */
-       protected function alterForm( HTMLForm $form ) {
+       protected function getForm() {
+               $form = parent::getForm();
                $form->setId( 'mw-specialmute-form' );
                $form->setHeaderText( $this->msg( 'specialmute-header', $this->target )->parse() );
                $form->setSubmitTextMsg( 'specialmute-submit' );
                $form->setSubmitID( 'save' );
+
+               return $form;
        }
 
        /**
         * @inheritDoc
         */
        protected function getFormFields() {
-               if ( !$this->enableUserEmailBlacklist || !$this->enableUserEmail ) {
-                       throw new ErrorPageError( 'specialmute', 'specialmute-error-email-blacklist-disabled' );
+               $fields = [];
+               if (
+                       $this->enableUserEmailBlacklist &&
+                       $this->enableUserEmail &&
+                       $this->getUser()->getEmailAuthenticationTimestamp()
+               ) {
+                       $fields['email-blacklist'] = [
+                               'type' => 'check',
+                               'label-message' => 'specialmute-label-mute-email',
+                               'default' => $this->isTargetBlacklisted( 'email-blacklist' ),
+                       ];
                }
 
-               if ( !$this->getUser()->getEmailAuthenticationTimestamp() ) {
-                       throw new ErrorPageError( 'specialmute', 'specialmute-error-email-preferences' );
-               }
+               Hooks::run( 'SpecialMuteModifyFormFields', [ $this, &$fields ] );
 
-               $fields['MuteEmail'] = [
-                       'type' => 'check',
-                       'label-message' => 'specialmute-label-mute-email',
-                       'default' => $this->isTargetBlacklisted(),
-               ];
+               if ( count( $fields ) == 0 ) {
+                       throw new ErrorPageError( 'specialmute', 'specialmute-error-no-options' );
+               }
 
                return $fields;
        }
@@ -192,18 +207,20 @@ class SpecialMute extends FormSpecialPage {
        }
 
        /**
+        * @param string $userOption
         * @return bool
         */
-       private function isTargetBlacklisted() {
-               $blacklist = $this->getBlacklist();
-               return in_array( $this->targetCentralId, $blacklist );
+       public function isTargetBlacklisted( $userOption ) {
+               $blacklist = $this->getBlacklist( $userOption );
+               return in_array( $this->targetCentralId, $blacklist, true );
        }
 
        /**
+        * @param string $userOption
         * @return array
         */
-       private function getBlacklist() {
-               $blacklist = $this->getUser()->getOption( 'email-blacklist' );
+       private function getBlacklist( $userOption ) {
+               $blacklist = $this->getUser()->getOption( $userOption );
                if ( !$blacklist ) {
                        return [];
                }
index 7e40594..fb265d3 100644 (file)
        "specialmute-success": "Your mute preferences have been updated. See all muted users in [[Special:Preferences|your preferences]].",
        "specialmute-submit": "Confirm",
        "specialmute-label-mute-email": "Mute emails from this user",
-       "specialmute-header": "Please select your mute preferences for {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Please select your mute preferences for <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "The username requested could not be found.",
-       "specialmute-error-email-blacklist-disabled": "Muting users from sending you emails is not enabled.",
-       "specialmute-error-email-preferences": "You must confirm your email address before you can mute a user. You may do so from [[Special:Preferences]].",
+       "specialmute-error-no-options": "Mute features are unavailable. This might be because: you haven't confirmed your email address or the wiki administrator has disabled email features and/or email blacklist for this wiki.",
        "specialmute-email-footer": "To manage email preferences for {{BIDI:$2}} please visit <$1>.",
        "specialmute-login-required": "Please log in to change your mute preferences.",
        "mute-preferences": "Mute preferences",
index a58010e..a348031 100644 (file)
        "specialmute-label-mute-email": "Label for the checkbox that mutes/unmutes emails from the specified user.",
        "specialmute-header": "Used as header text on [[Special:Mute]]. Shown before the form with the muting options.\n* $1 - User selected for muting",
        "specialmute-error-invalid-user": "Error displayed when the username cannot be found.",
-       "specialmute-error-email-blacklist-disabled": "Error displayed when email blacklist is not enabled.",
-       "specialmute-error-email-preferences": "Error displayed when the user has not confirmed their email address.",
+       "specialmute-error-no-options": "Error displayed when there are no options available to mute on [[Special:Mute]].",
        "specialmute-email-footer": "Email footer in plain text linking to [[Special:Mute]] preselecting the sender to manage muting options.\n* $1 - Url linking to [[Special:Mute]].\n* $2 - The user sending the email.",
        "specialmute-login-required": "Error displayed when a user tries to access [[Special:Mute]] before logging in.",
        "mute-preferences": "Link in the sidebar to manage muting preferences for a user. It links to [[Special:Mute]] with the user in context as the subpage.",
index e31357c..a57745b 100644 (file)
@@ -35,10 +35,15 @@ class SpecialMuteTest extends SpecialPageTestBase {
 
        /**
         * @covers SpecialMute::execute
-        * @expectedExceptionMessage Muting users from sending you emails is not enabled
+        * @expectedExceptionMessage Mute features are unavailable
         * @expectedException ErrorPageError
         */
        public function testEmailBlacklistNotEnabled() {
+               $this->setTemporaryHook(
+                       'SpecialMuteModifyFormFields',
+                       null
+               );
+
                $this->setMwGlobals( [
                        'wgEnableUserEmailBlacklist' => false
                ] );
@@ -72,7 +77,7 @@ class SpecialMuteTest extends SpecialPageTestBase {
                $loggedInUser->confirmEmail();
                $loggedInUser->saveSettings();
 
-               $fauxRequest = new FauxRequest( [ 'wpMuteEmail' => 1 ], true );
+               $fauxRequest = new FauxRequest( [ 'wpemail-blacklist' => true ], true );
                list( $html, ) = $this->executeSpecialPage(
                        $targetUser->getName(), $fauxRequest, 'qqx', $loggedInUser
                );
@@ -99,7 +104,7 @@ class SpecialMuteTest extends SpecialPageTestBase {
                $loggedInUser->confirmEmail();
                $loggedInUser->saveSettings();
 
-               $fauxRequest = new FauxRequest( [ 'wpMuteEmail' => false ], true );
+               $fauxRequest = new FauxRequest( [ 'wpemail-blacklist' => false ], true );
                list( $html, ) = $this->executeSpecialPage(
                        $targetUser->getName(), $fauxRequest, 'qqx', $loggedInUser
                );