Index: trunk/phase3/includes/Xml.php |
— | — | @@ -472,6 +472,25 @@ |
473 | 473 | |
474 | 474 | return $s; |
475 | 475 | } |
| 476 | + |
| 477 | + /** |
| 478 | + * Shortcut for creating textareas. |
| 479 | + * |
| 480 | + * @param $name The 'name' for the textarea |
| 481 | + * @param $content Content for the textarea |
| 482 | + * @param $cols The number of columns for the textarea |
| 483 | + * @param $rows The number of rows for the textarea |
| 484 | + * @param $attribs Any other attributes for the textarea |
| 485 | + */ |
| 486 | + public static function textarea( $name, $content, $cols = 40, $rows = 5, $attribs = array() ) { |
| 487 | + return self::element( 'textarea', |
| 488 | + array( 'name' => $name, |
| 489 | + 'id' => $name, |
| 490 | + 'cols' => $cols, |
| 491 | + 'rows' => $rows |
| 492 | + ) + $attribs, |
| 493 | + $content ); |
| 494 | + } |
476 | 495 | |
477 | 496 | /** |
478 | 497 | * Returns an escaped string suitable for inclusion in a string literal |
— | — | @@ -606,30 +625,30 @@ |
607 | 626 | |
608 | 627 | /** |
609 | 628 | * Generate a form (without the opening form element). |
610 | | - * Output DOES include a submit button. |
| 629 | + * Output optionally includes a submit button. |
611 | 630 | * @param $fields Associative array, key is message corresponding to a description for the field (colon is in the message), value is appropriate input. |
612 | 631 | * @param $submitLabel A message containing a label for the submit button. |
613 | 632 | * @return string HTML form. |
614 | 633 | */ |
615 | | - public static function buildForm( $fields, $submitLabel ) { |
| 634 | + public static function buildForm( $fields, $submitLabel = null ) { |
616 | 635 | $form = ''; |
617 | 636 | $form .= "<table><tbody>"; |
618 | 637 | |
619 | 638 | foreach( $fields as $labelmsg => $input ) { |
620 | 639 | $id = "mw-$labelmsg"; |
| 640 | + |
621 | 641 | $form .= Xml::openElement( 'tr', array( 'id' => $id ) ); |
622 | | - |
623 | | - $form .= Xml::element( 'td', array('valign' => 'top'), wfMsg( $labelmsg ) ); |
624 | | - |
| 642 | + $form .= Xml::tags( 'td', array('valign'=>'top','align' => 'right'), wfMsgExt( $labelmsg, array('parseinline') ) ); |
625 | 643 | $form .= Xml::openElement( 'td' ) . $input . Xml::closeElement( 'td' ); |
626 | | - |
627 | 644 | $form .= Xml::closeElement( 'tr' ); |
628 | 645 | } |
629 | 646 | |
630 | 647 | $form .= "</tbody></table>"; |
| 648 | + |
| 649 | + if ($submitLabel) { |
| 650 | + $form .= Xml::submitButton( wfMsg($submitLabel) ); |
| 651 | + } |
631 | 652 | |
632 | | - $form .= Xml::submitButton( wfMsg($submitLabel) ); |
633 | | - |
634 | 653 | return $form; |
635 | 654 | } |
636 | 655 | } |
Index: trunk/phase3/includes/Article.php |
— | — | @@ -2250,8 +2250,10 @@ |
2251 | 2251 | wfDebug( __METHOD__."\n" ); |
2252 | 2252 | |
2253 | 2253 | $id = $this->getId(); |
| 2254 | + |
| 2255 | + $error = ''; |
2254 | 2256 | |
2255 | | - if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) { |
| 2257 | + if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason, &$error))) { |
2256 | 2258 | if ( $this->doDeleteArticle( $reason, $suppress ) ) { |
2257 | 2259 | $deleted = $this->mTitle->getPrefixedText(); |
2258 | 2260 | |
— | — | @@ -2264,7 +2266,10 @@ |
2265 | 2267 | $wgOut->returnToMain( false ); |
2266 | 2268 | wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason, $id)); |
2267 | 2269 | } else { |
2268 | | - $wgOut->showFatalError( wfMsg( 'cannotdelete' ) ); |
| 2270 | + if ($error = '') |
| 2271 | + $wgOut->showFatalError( wfMsg( 'cannotdelete' ) ); |
| 2272 | + else |
| 2273 | + $wgOut->showFatalError( $error ); |
2269 | 2274 | } |
2270 | 2275 | } |
2271 | 2276 | } |
Index: trunk/phase3/includes/EditPage.php |
— | — | @@ -62,6 +62,7 @@ |
63 | 63 | var $autoSumm = ''; |
64 | 64 | var $hookError = ''; |
65 | 65 | var $mPreviewTemplates; |
| 66 | + var $mBaseRevision = false; |
66 | 67 | |
67 | 68 | # Form values |
68 | 69 | var $save = false, $preview = false, $diff = false; |
— | — | @@ -1722,8 +1723,7 @@ |
1723 | 1724 | $db = wfGetDB( DB_MASTER ); |
1724 | 1725 | |
1725 | 1726 | // This is the revision the editor started from |
1726 | | - $baseRevision = Revision::loadFromTimestamp( |
1727 | | - $db, $this->mTitle, $this->edittime ); |
| 1727 | + $baseRevision = $this->getBaseRevision(); |
1728 | 1728 | if( is_null( $baseRevision ) ) { |
1729 | 1729 | wfProfileOut( $fname ); |
1730 | 1730 | return false; |
— | — | @@ -2321,4 +2321,15 @@ |
2322 | 2322 | return false; |
2323 | 2323 | } |
2324 | 2324 | } |
| 2325 | + |
| 2326 | + function getBaseRevision() { |
| 2327 | + if ($this->mBaseRevision == false) { |
| 2328 | + $db = wfGetDB( DB_MASTER ); |
| 2329 | + $baseRevision = Revision::loadFromTimestamp( |
| 2330 | + $db, $editor->mTitle, $editor->edittime ); |
| 2331 | + return $this->mBaseRevision = $baseRevision; |
| 2332 | + } else { |
| 2333 | + return $this->mBaseRevision; |
| 2334 | + } |
| 2335 | + } |
2325 | 2336 | } |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -1049,9 +1049,10 @@ |
1050 | 1050 | * @param string $action action that permission needs to be checked for |
1051 | 1051 | * @param User $user user to check |
1052 | 1052 | * @param bool $doExpensiveQueries Set this to false to avoid doing unnecessary queries. |
| 1053 | + * @param array $ignoreErrors Set this to a list of message keys whose corresponding errors may be ignored. |
1053 | 1054 | * @return array Array of arrays of the arguments to wfMsg to explain permissions problems. |
1054 | 1055 | */ |
1055 | | - public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true ) { |
| 1056 | + public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) { |
1056 | 1057 | if( !StubObject::isRealObject( $user ) ) { |
1057 | 1058 | //Since StubObject is always used on globals, we can unstub $wgUser here and set $user = $wgUser |
1058 | 1059 | global $wgUser; |
— | — | @@ -1116,6 +1117,16 @@ |
1117 | 1118 | $errors[] = array( ($block->mAuto ? 'autoblockedtext' : 'blockedtext'), $link, $reason, $ip, $name, |
1118 | 1119 | $blockid, $blockExpiry, $intended, $blockTimestamp ); |
1119 | 1120 | } |
| 1121 | + |
| 1122 | + // Remove the errors being ignored. |
| 1123 | + |
| 1124 | + foreach( $errors as $index => $error ) { |
| 1125 | + $error_key = is_array($error) ? $error[0] : $error; |
| 1126 | + |
| 1127 | + if (in_array( $error_key, $ignoreErrors )) { |
| 1128 | + unset($errors[$index]); |
| 1129 | + } |
| 1130 | + } |
1120 | 1131 | |
1121 | 1132 | return $errors; |
1122 | 1133 | } |
Index: trunk/phase3/includes/Block.php |
— | — | @@ -17,7 +17,7 @@ |
18 | 18 | { |
19 | 19 | /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry, |
20 | 20 | $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName, |
21 | | - $mBlockEmail, $mByName; |
| 21 | + $mBlockEmail, $mByName, $mAngryAutoblock; |
22 | 22 | /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster; |
23 | 23 | |
24 | 24 | const EB_KEEP_EXPIRED = 1; |
— | — | @@ -46,6 +46,7 @@ |
47 | 47 | $this->mForUpdate = false; |
48 | 48 | $this->mFromMaster = false; |
49 | 49 | $this->mByName = false; |
| 50 | + $this->mAngryAutoblock = false; |
50 | 51 | $this->initialiseRange(); |
51 | 52 | } |
52 | 53 | |
— | — | @@ -430,17 +431,30 @@ |
431 | 432 | |
432 | 433 | if ($this->mEnableAutoblock && $this->mUser) { |
433 | 434 | wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n"); |
| 435 | + |
| 436 | + $options = array( 'ORDER BY' => 'rc_timestamp DESC' ); |
| 437 | + $conds = array( 'rc_user_text' => $this->mAddress ); |
| 438 | + |
| 439 | + if ($this->mAngryAutoblock) { |
| 440 | + // Block any IP used in the last 7 days. Up to five IPs. |
| 441 | + $conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - (7*86400) ) ); |
| 442 | + $options['LIMIT'] = 5; |
| 443 | + } else { |
| 444 | + // Just the last IP used. |
| 445 | + $options['LIMIT'] = 1; |
| 446 | + } |
434 | 447 | |
435 | | - $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ), |
436 | | - __METHOD__ , array( 'ORDER BY' => 'rc_timestamp DESC' ) ); |
| 448 | + $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds, |
| 449 | + __METHOD__ , $options); |
437 | 450 | |
438 | | - if ( !$row || !$row->rc_ip ) { |
| 451 | + if ( !$dbr->numRows( $res ) ) { |
439 | 452 | #No results, don't autoblock anything |
440 | 453 | wfDebug("No IP found to retroactively autoblock\n"); |
441 | 454 | } else { |
442 | | - #Limit is 1, so no loop needed. |
443 | | - $retroblockip = $row->rc_ip; |
444 | | - return $this->doAutoblock( $retroblockip, true ); |
| 455 | + while ( $row = $dbr->fetchObject( $res ) ) { |
| 456 | + if ( $row->rc_ip ) |
| 457 | + $this->doAutoblock( $row->rc_ip ); |
| 458 | + } |
445 | 459 | } |
446 | 460 | } |
447 | 461 | } |