Some cleanup to ProtectionForm:
authorAlexandre Emsenhuber <ialex@users.mediawiki.org>
Tue, 1 Nov 2011 15:45:52 +0000 (15:45 +0000)
committerAlexandre Emsenhuber <ialex@users.mediawiki.org>
Tue, 1 Nov 2011 15:45:52 +0000 (15:45 +0000)
* When the user doesn't have permission to protect/unprotect the page, display a page with the title set to "View protection level for ...", then the permissions errors and the current protection levels. Except for the title, this was already the case for permissions errors, but when the database was read-only this was throwing an exception due to the change in OutputPage::readOnlyPage()
* Moved check for NS_MEDIAWIKI a level up, so that is it also catched on page save, and make the output in such case much more user friendly
* Changed edit token to be salted with array( 'protect', 'page name' ) (as for action=watch)
* Allow extensions to return false in ProtectionForm::save hook for consistency with other hooks and in that case fill the error message with 'hookaborted' if the extension does not provide an customised error message.
* Changed ProtectionForm::show() to accept an array of message name and its parameters in addition of a string with raw HTML and converted calls to use the new method. This also means that ProtectionForm::save can use this
* Removed the setSubtitle() call for the 'formerror' message in case of error since it's overriden by the "back link"

docs/hooks.txt
includes/ProtectionForm.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
maintenance/language/messages.inc

index cb0120e..33bc594 100644 (file)
@@ -1514,7 +1514,7 @@ $output: a string of the form HTML so far
 
 'ProtectionForm::save': called when a protection form is submitted
 $article: the title being (un)protected
-$errorMsg: an html message string of an error
+$errorMsg: an html message string of an error or an array of message name and its parameters
 
 'ProtectionForm::showLogExtract': called after the protection log extract is shown
 $article: the page the form is shown for
index ae0479a..5341fe5 100644 (file)
@@ -66,8 +66,11 @@ class ProtectionForm {
                
                // Check if the form should be disabled.
                // If it is, the form will be available in read-only to show levels.
-               $this->mPermErrors = $this->mTitle->getUserPermissionsErrors('protect',$wgUser);
-               $this->disabled = wfReadOnly() || $this->mPermErrors != array();
+               $this->mPermErrors = $this->mTitle->getUserPermissionsErrors( 'protect', $wgUser );
+               if ( wfReadOnly() ) {
+                       $this->mPermErrors[] = array( 'readonlytext', wfReadOnlyReason() );
+               }
+               $this->disabled = $this->mPermErrors != array();
                $this->disabledAttrib = $this->disabled
                        ? array( 'disabled' => 'disabled' )
                        : array();
@@ -180,6 +183,11 @@ class ProtectionForm {
         */
        function execute() {
                global $wgRequest, $wgOut;
+
+               if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+                       throw new ErrorPageError( 'protect-badnamespace-title', 'protect-badnamespace-text' );
+               }
+
                if( $wgRequest->wasPosted() ) {
                        if( $this->save() ) {
                                $q = $this->mArticle->isRedirect() ? 'redirect=no' : '';
@@ -200,19 +208,13 @@ class ProtectionForm {
 
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
 
-               if( is_null( $this->mTitle ) ||
-                       $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
-                       $wgOut->showFatalError( wfMsg( 'badarticleerror' ) );
-                       return;
-               }
-
-               list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
-
-               if ( $err != "" ) {
-                       $wgOut->setSubtitle( wfMsgHtml( 'formerror' ) );
+               if ( is_array( $err ) ) {
+                       $wgOut->wrapWikiMsg( "<p class='error'>\n$1\n</p>\n", $err );
+               } elseif ( is_string( $err ) ) {
                        $wgOut->addHTML( "<p class='error'>{$err}</p>\n" );
                }
 
+               list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
                if ( $cascadeSources && count($cascadeSources) > 0 ) {
                        $titles = '';
 
@@ -223,23 +225,20 @@ class ProtectionForm {
                        $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count($cascadeSources) ) );
                }
 
-               $titleLink = Linker::link( $this->mTitle );
-               $wgOut->setPageTitle( wfMessage( 'protect-title', $this->mTitle->getPrefixedText() ) );
-               $wgOut->setSubtitle( wfMsg( 'protect-backlink', $titleLink ) );
-
                # Show an appropriate message if the user isn't allowed or able to change
                # the protection settings at this time
-               if( $this->disabled ) {
-                       if( wfReadOnly() ) {
-                               $wgOut->readOnlyPage();
-                       } elseif( $this->mPermErrors ) {
-                               $wgOut->showPermissionsErrorPage( $this->mPermErrors );
-                       }
+               if ( $this->disabled ) {
+                       $wgOut->setPageTitle( wfMessage( 'protect-title-notallowed', $this->mTitle->getPrefixedText() ) );
+                       $wgOut->addWikiText( $wgOut->formatPermissionsErrorMessage( $this->mPermErrors, 'protect' ) );
                } else {
+                       $wgOut->setPageTitle( wfMessage( 'protect-title', $this->mTitle->getPrefixedText() ) );
                        $wgOut->addWikiMsg( 'protect-text',
                                wfEscapeWikiText( $this->mTitle->getPrefixedText() ) );
                }
 
+               $titleLink = Linker::link( $this->mTitle );
+               $wgOut->setSubtitle( wfMsg( 'protect-backlink', $titleLink ) );
+
                $wgOut->addHTML( $this->buildForm() );
 
                $this->showLogExtract( $wgOut );
@@ -260,8 +259,8 @@ class ProtectionForm {
                }
 
                $token = $wgRequest->getVal( 'wpEditToken' );
-               if ( !$wgUser->matchEditToken( $token ) ) {
-                       $this->show( wfMsg( 'sessionfailure' ) );
+               if ( !$wgUser->matchEditToken( $token, array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) ) {
+                       $this->show( array( 'sessionfailure' ) );
                        return false;
                }
 
@@ -279,11 +278,11 @@ class ProtectionForm {
                        if( empty($this->mRestrictions[$action]) )
                                continue; // unprotected
                        if ( !$expiry[$action] ) {
-                               $this->show( wfMsg( 'protect_expiry_invalid' ) );
+                               $this->show( array( 'protect_expiry_invalid' ) );
                                return false;
                        }
                        if ( $expiry[$action] < wfTimestampNow() ) {
-                               $this->show( wfMsg( 'protect_expiry_old' ) );
+                               $this->show( array( 'protect_expiry_old' ) );
                                return false;
                        }
                }
@@ -308,10 +307,17 @@ class ProtectionForm {
                        throw new FatalError( "Unknown error at restriction save time." );
                }
 
+               /**
+                * Give extensions a change to handle added form items
+                *
+                * @since 1.19 you can (and you should) return false to abort saving;
+                *             you can also return an array of message name and its parameters
+                */
                $errorMsg = '';
-               # Give extensions a change to handle added form items
-               if( !wfRunHooks( 'ProtectionForm::save', array($this->mArticle,&$errorMsg) ) ) {
-                       throw new FatalError( "Unknown hook error at restriction save time." );
+               if( !wfRunHooks( 'ProtectionForm::save', array( $this->mArticle, &$errorMsg ) ) ) {
+                       if ( $errorMsg == '' ) {
+                               $errorMsg = array( 'hookaborted' );
+                       }
                }
                if( $errorMsg != '' ) {
                        $this->show( $errorMsg );
@@ -343,7 +349,6 @@ class ProtectionForm {
                        $out .= Xml::openElement( 'form', array( 'method' => 'post',
                                'action' => $this->mTitle->getLocalUrl( 'action=protect' ),
                                'id' => 'mw-Protect-Form', 'onsubmit' => 'ProtectionForm.enableUnchainedInputs(true)' ) );
-                       $out .= Html::hidden( 'wpEditToken',$wgUser->editToken() );
                }
 
                $out .= Xml::openElement( 'fieldset' ) .
@@ -510,6 +515,7 @@ class ProtectionForm {
                }
 
                if ( !$this->disabled ) {
+                       $out .= Html::hidden( 'wpEditToken', $wgUser->getEditToken( array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) );
                        $out .= Xml::closeElement( 'form' );
                        $wgOut->addScript( $this->buildCleanupScript() );
                }
index fcf4c81..a3b47ee 100644 (file)
@@ -2848,7 +2848,10 @@ See the [[Special:ProtectedPages|protected pages list]] for the list of currentl
 'unprotectedarticle'          => 'removed protection from "[[$1]]"',
 'movedarticleprotection'      => 'moved protection settings from "[[$2]]" to "[[$1]]"',
 'protect-title'               => 'Change protection level for "$1"',
+'protect-title-notallowed'    => 'View protection level of "$1"',
 'prot_1movedto2'              => '[[$1]] moved to [[$2]]',
+'protect-badnamespace-title'  => 'Non-protectable namespace',
+'protect-badnamespace-text'   => 'Pages in this namespace cannot be protected.',
 'protect-backlink'            => '← $1', # only translate this message to other languages if you have to change it
 'protect-legend'              => 'Confirm protection',
 'protectcomment'              => 'Reason:',
index 3edb887..40566bb 100644 (file)
@@ -2509,7 +2509,10 @@ In other cases the message {{msg-mw|revertpage}} is used.',
 Example:
 <code>00:51, 16 September 2010 Siebrand +(Talk • contribs • block) moved protection settings from "User:Siebrand/prot-move" to "User:Siebrand/prot-moved" ‎ (User:Siebrand/prot-move moved to User:Siebrand/prot-moved: prot_move test.)</code>',
 'protect-title'               => 'Title for the protection form. $1 is the title of the page to be (un)protected.',
+'protect-title-notallowed'    => 'Same as {{msg-mw|protect-title}}, but when the user does not have the right to change protection levels.',
 'prot_1movedto2'              => 'Message description: [[mw:Manual:Interface/1movedto2]]',
+'protect-badnamespace-title'  => 'Title of error page when trying to access action=protect on a non-protectable namespace (currently this only for the MediaWiki: namespace).',
+'protect-badnamespace-text'   => 'Content of the error page that goes with {{msg-mw|protect-badnamespace-title}}.',
 'protect-backlink'            => '{{optional|Translate it only if you have to change it, i.e. for RTL wikis}}
 
 Shown as subtitle of the protection form. $1 is the title of the page to be (un)protected.',
index 90f8b2d..a478683 100644 (file)
@@ -1894,7 +1894,10 @@ $wgMessageStructure = array(
                'unprotectedarticle',
                'movedarticleprotection',
                'protect-title',
+               'protect-title-notallowed',
                'prot_1movedto2',
+               'protect-badnamespace-title',
+               'protect-badnamespace-text',
                'protect-backlink',
                'protect-legend',
                'protectcomment',