Core changes for AbuseFilter extension.
authorAndrew Garrett <werdna@users.mediawiki.org>
Fri, 27 Jun 2008 06:24:42 +0000 (06:24 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Fri, 27 Jun 2008 06:24:42 +0000 (06:24 +0000)
In particular:
Xml.php
* Add textarea method to Xml class.
* Make submit button optional for Xml::buildForm
* Right-align labels in buildForm.

Article.php:
* Make ArticleDelete hook display a real error

EditPage.php:
* Split off getBaseRevision()

Title.php:
* Allow errors to be ignored to be sent to getUserPermissionsErrors.
* Allow AbortMove hook to display a real error.

Block.php:
* Add 'mAngryAutoblock' option, for blocks by software, which does retroactive autoblocks on the last 5 IPs used in the last 7 days.

includes/Article.php
includes/Block.php
includes/EditPage.php
includes/Title.php
includes/Xml.php

index bce7202..2ce6905 100644 (file)
@@ -2250,8 +2250,10 @@ class Article {
                wfDebug( __METHOD__."\n" );
                
                $id = $this->getId();
+               
+               $error = '';
 
-               if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) {
+               if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason, &$error))) {
                        if ( $this->doDeleteArticle( $reason, $suppress ) ) {
                                $deleted = $this->mTitle->getPrefixedText();
 
@@ -2264,7 +2266,10 @@ class Article {
                                $wgOut->returnToMain( false );
                                wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason, $id));
                        } else {
-                               $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+                               if ($error = '')
+                                       $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+                               else
+                                       $wgOut->showFatalError( $error );
                        }
                }
        }
index 2a1ad69..b400912 100644 (file)
@@ -17,7 +17,7 @@ class Block
 {
        /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
                                $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
-                               $mBlockEmail, $mByName;
+                               $mBlockEmail, $mByName, $mAngryAutoblock;
        /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster;
 
        const EB_KEEP_EXPIRED = 1;
@@ -46,6 +46,7 @@ class Block
                $this->mForUpdate = false;
                $this->mFromMaster = false;
                $this->mByName = false;
+               $this->mAngryAutoblock = false;
                $this->initialiseRange();
        }
 
@@ -430,17 +431,30 @@ class Block
 
                if ($this->mEnableAutoblock && $this->mUser) {
                        wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
+                       
+                       $options = array( 'ORDER BY' => 'rc_timestamp DESC' );
+                       $conds = array( 'rc_user_text' => $this->mAddress );
+                       
+                       if ($this->mAngryAutoblock) {
+                               // Block any IP used in the last 7 days. Up to five IPs.
+                               $conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - (7*86400) ) );
+                               $options['LIMIT'] = 5;
+                       } else {
+                               // Just the last IP used.
+                               $options['LIMIT'] = 1;
+                       }
 
-                       $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ),
-                               __METHOD__ , array( 'ORDER BY' => 'rc_timestamp DESC' ) );
+                       $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
+                               __METHOD__ ,  $options);
 
-                       if ( !$row || !$row->rc_ip ) {
+                       if ( !$dbr->numRows( $res ) ) {
                                #No results, don't autoblock anything
                                wfDebug("No IP found to retroactively autoblock\n");
                        } else {
-                               #Limit is 1, so no loop needed.
-                               $retroblockip = $row->rc_ip;
-                               return $this->doAutoblock( $retroblockip, true );
+                               while ( $row = $dbr->fetchObject( $res ) ) {
+                                       if ( $row->rc_ip )
+                                               $this->doAutoblock( $row->rc_ip );
+                               }
                        }
                }
        }
index e861b4b..c898b9a 100644 (file)
@@ -62,6 +62,7 @@ class EditPage {
        var $autoSumm = '';
        var $hookError = '';
        var $mPreviewTemplates;
+       var $mBaseRevision = false;
 
        # Form values
        var $save = false, $preview = false, $diff = false;
@@ -1722,8 +1723,7 @@ END
                $db = wfGetDB( DB_MASTER );
 
                // This is the revision the editor started from
-               $baseRevision = Revision::loadFromTimestamp(
-                       $db, $this->mTitle, $this->edittime );
+               $baseRevision = $this->getBaseRevision();
                if( is_null( $baseRevision ) ) {
                        wfProfileOut( $fname );
                        return false;
@@ -2321,4 +2321,15 @@ END
                                return false;
                }
        }
+       
+       function getBaseRevision() {
+               if ($this->mBaseRevision == false) {
+                       $db = wfGetDB( DB_MASTER );
+                       $baseRevision = Revision::loadFromTimestamp(
+                               $db, $editor->mTitle, $editor->edittime );
+                       return $this->mBaseRevision = $baseRevision;
+               } else {
+                       return $this->mBaseRevision;
+               }
+       }
 }
index 8cbbbd1..1b0512b 100644 (file)
@@ -1049,9 +1049,10 @@ class Title {
         * @param string $action action that permission needs to be checked for
         * @param User $user user to check
         * @param bool $doExpensiveQueries Set this to false to avoid doing unnecessary queries.
+        * @param array $ignoreErrors Set this to a list of message keys whose corresponding errors may be ignored.
         * @return array Array of arrays of the arguments to wfMsg to explain permissions problems.
         */
-       public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true ) {
+       public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) {
                if( !StubObject::isRealObject( $user ) ) {
                        //Since StubObject is always used on globals, we can unstub $wgUser here and set $user = $wgUser
                        global $wgUser;
@@ -1116,6 +1117,16 @@ class Title {
                        $errors[] = array( ($block->mAuto ? 'autoblockedtext' : 'blockedtext'), $link, $reason, $ip, $name, 
                                $blockid, $blockExpiry, $intended, $blockTimestamp );
                }
+               
+               // Remove the errors being ignored.
+               
+               foreach( $errors as $index => $error ) {
+                       $error_key = is_array($error) ? $error[0] : $error;
+                       
+                       if (in_array( $error_key, $ignoreErrors )) {
+                               unset($errors[$index]);
+                       }
+               }
 
                return $errors;
        }
index 9f9be3c..4feff6d 100644 (file)
@@ -472,6 +472,25 @@ class Xml {
 
                return $s;
        }
+       
+       /**
+        * Shortcut for creating textareas.
+        *
+        * @param $name The 'name' for the textarea
+        * @param $content Content for the textarea
+        * @param $cols The number of columns for the textarea
+        * @param $rows The number of rows for the textarea
+        * @param $attribs Any other attributes for the textarea
+        */
+       public static function textarea( $name, $content, $cols = 40, $rows = 5, $attribs = array() ) {
+               return self::element( 'textarea',
+                                       array(  'name' => $name,
+                                               'id' => $name,
+                                               'cols' => $cols,
+                                               'rows' => $rows
+                                       ) + $attribs,
+                                       $content );
+       }
 
        /**
         * Returns an escaped string suitable for inclusion in a string literal
@@ -606,29 +625,29 @@ class Xml {
        
        /**
        * Generate a form (without the opening form element).
-       * Output DOES include a submit button.
+       * Output optionally includes a submit button.
        * @param $fields Associative array, key is message corresponding to a description for the field (colon is in the message), value is appropriate input.
        * @param $submitLabel A message containing a label for the submit button.
        * @return string HTML form.
        */
-       public static function buildForm( $fields, $submitLabel ) {
+       public static function buildForm( $fields, $submitLabel = null ) {
                $form = '';
                $form .= "<table><tbody>";
        
                foreach( $fields as $labelmsg => $input ) {
                        $id = "mw-$labelmsg";
+                       
                        $form .= Xml::openElement( 'tr', array( 'id' => $id ) );
-       
-                       $form .= Xml::element( 'td', array('valign' => 'top'), wfMsg( $labelmsg ) );
-       
+                       $form .= Xml::tags( 'td', array('valign'=>'top','align' => 'right'), wfMsgExt( $labelmsg, array('parseinline') ) );
                        $form .= Xml::openElement( 'td' ) . $input . Xml::closeElement( 'td' );
-       
                        $form .= Xml::closeElement( 'tr' );
                }
        
                $form .= "</tbody></table>";
-       
-               $form .= Xml::submitButton( wfMsg($submitLabel) );
+               
+               if ($submitLabel) {     
+                       $form .= Xml::submitButton( wfMsg($submitLabel) );
+               }
        
                return $form;
        }