New feature: You can edit summaries and change the Minor Edit flag.
authorNicholas Pisarro, Jr <npassoc@users.mediawiki.org>
Fri, 10 Dec 2004 04:49:27 +0000 (04:49 +0000)
committerNicholas Pisarro, Jr <npassoc@users.mediawiki.org>
Fri, 10 Dec 2004 04:49:27 +0000 (04:49 +0000)
* Documented at http://meta.wikimedia.org/wiki/Feature_to_edit_summaries

12 files changed:
includes/ChangesList.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditComment.php [new file with mode: 0644]
includes/GlobalFunctions.php
includes/OutputPage.php
includes/PageHistory.php
includes/RecentChange.php
includes/SpecialContributions.php
index.php
languages/Language.php
skins/common/images/editcomment_icon.gif [new file with mode: 0644]

index 7e9807b..45fef5f 100644 (file)
@@ -92,9 +92,20 @@ class ChangesList {
                $r .= $rcObj->usertalklink ;
 
                # Comment
-                if ( $rc_comment != '' && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
-                       $rc_comment=$this->skin->formatComment($rc_comment, $rcObj->getTitle());
-                       $r .= $wgContLang->emphasize( ' ('.$rc_comment.')' );
+               if ( ($rc_comment != '' || $rc_type == RC_EDIT_COMMENT) && 
+                        $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
+               
+                       $rc_comment = $this->skin->formatComment($rc_comment, $rcObj->getTitle()); 
+               
+                       # If a summary comment change, we want to form the message "was ($rc_moved_to_title)
+                       # now ($rc_comment)".
+                       if ( $rc_type == RC_EDIT_COMMENT ) {
+                               $rc_comment = $wgContLang->emphasize( '(' . $rc_comment . ')' );
+                               $rc_moved_to_title = $this->skin->formatComment( $rc_moved_to_title, $rcObj->getTitle() );
+                               $rc_moved_to_title = $wgContLang->emphasize( '(' . $rc_moved_to_title . ')' );
+                               $r .= ' ' . wfMsg( 'ecrccommentformat', $rc_moved_to_title, $rc_comment );
+                       } else
+                               $r .= $wgContLang->emphasize( ' ('.$rc_comment.')' );
                }
 
                $r .= "<br />\n" ;
@@ -324,6 +335,20 @@ class ChangesList {
                        $msg = ( $rc_type == RC_MOVE ) ? '1movedto2' : '1movedto2_redir';
                        $s .= wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
                                $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
+               } else if ( $rc_type == RC_EDIT_COMMENT ) { 
+                       # Diff
+                       $s .= '(' . wfMsg( 'diff' ) . ') (';
+                       # History link
+                       $s .= $this->skin->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' );
+                       $s .= ') . . ';
+
+                       # M and ! (minor and unpatrolled)
+                       if ( $rc_minor ) { $s .= '<span class="minor">'.$message["minoreditletter"].'</span> '; }
+                       if ( !$rc_patrolled ) { $s .= '<span class="unpatrolled">!</span> '; }
+                       
+                       # Put a link to the revision the comment is for, in a message.
+                       $s .= wfMsg( "eccommentchanged" , 
+                                               $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no&oldid=' . $rc_this_oldid ) );
                } elseif( $rc_namespace == NS_SPECIAL && preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
                        # Log updates, etc
                        $logtype = $matches[1];
@@ -408,9 +433,20 @@ class ChangesList {
                if($userTalkLink) $s.=' ('.$userTalkLink.')';
 
                # Add comment
-               if ( '' != $rc_comment && '*' != $rc_comment && $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
-                       $rc_comment = $this->skin->formatComment($rc_comment,$rc->getTitle());
-                       $s .= $wgContLang->emphasize(' (' . $rc_comment . ')');
+               if ( (('' != $rc_comment && '*' != $rc_comment) || $rc_type == RC_EDIT_COMMENT) && 
+                    $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) {
+                       
+                       $rc_comment = $this->skin->formatComment( $rc_comment, $rc->getTitle() );
+                       
+                       # If a summary comment change, we want to form the message "was ($rc_moved_to_title)
+                       # now ($rc_comment)".
+                       if ( $rc_type == RC_EDIT_COMMENT ) {
+                               $rc_comment = $wgContLang->emphasize( '(' . $rc_comment . ')' );
+                               $rc_moved_to_title = $this->skin->formatComment( $rc_moved_to_title, $rc->getTitle() );
+                               $rc_moved_to_title = $wgContLang->emphasize( '(' . $rc_moved_to_title . ')' );
+                               $s .= ' ' . wfMsg( 'ecrccommentformat', $rc_moved_to_title, $rc_comment );
+                       } else
+                               $s .= $wgContLang->emphasize(' (' . $rc_comment . ')');
                }
                $s .= "</li>\n";
 
@@ -461,6 +497,10 @@ class ChangesList {
                        $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir";
                        $clink = wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
                          $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
+               } else if ( $rc_type == RC_EDIT_COMMENT ) { 
+                       # Put a link to the revision the comment is for, in a message.
+                       $clink = wfMsg( "eccommentchanged" , 
+                                                       $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no&oldid=' . $rc_this_oldid ) );
                } elseif( $rc_namespace == NS_SPECIAL && preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) {
                        # Log updates, etc
                        $logtype = $matches[1];
@@ -485,7 +525,9 @@ class ChangesList {
                } else {
                        $rcIdQuery = '';
                }
-               if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+               if ( ( $rc_type == RC_NEW && $rc_this_oldid == 0 ) || $rc_type == RC_LOG || 
+                          $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT || 
+                          $rc_type == RC_EDIT_COMMENT) {
                        $curLink = $message['cur'];
                        $diffLink = $message['diff'];
                } else {
@@ -543,7 +585,7 @@ class ChangesList {
                # Page moves go on their own line
                $title = $rc->getTitle();
                $secureName = $title->getPrefixedDBkey();
-               if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
+               if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT || $rc_type == RC_EDIT_COMMENT ) {
                        # Use an @ character to prevent collision with page names
                        $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
                } else {
index 690671b..2762303 100644 (file)
@@ -685,6 +685,19 @@ $wgCapitalLinks = true;
 # can be imported, these should be 'trusted'.
 $wgImportSources = array();
 
+# Set to true to allow editing comments (revision summaries) via
+# clicking on editcomment_icon.gif. This will appear in History
+# and Contributions listings for just revisions made by the
+# logged in user. SysOps may edit all revisions.
+$wgAllowEditComments = false;
+
+# If $wgAllowEditComments, the maximum age in minutes of a
+# revision a user may revise the comment of, -1 = forever,
+# 0 = never. Sysops may always edit a comment.
+# Note: The user is given an extra 2 minutes once they start
+# editing a comment.
+$wgUserEditCommentTimeout = 0;
+
 # Set this to the number of authors that you want to be credited below an
 # article text. Set it to zero to hide the attribution block, and a
 # negative number (like -1) to show all authors. Note that this will
index ab7507a..c7bfd9b 100644 (file)
@@ -80,4 +80,10 @@ $wgAvailableRights = array('read', 'edit', 'move', 'delete', 'undelete',
 'protect', 'block', 'userrights', 'createaccount', 'upload', 'asksql',
 'rollback', 'patrol', 'editinterface', 'siteadmin', 'bot');
 
+/**#@+
+ * Edit Comments really needs its own separate rights.
+ * Two separate rights are required; edit all comments, edit your own comment.
+ */
+define('EDIT_COMMENT_ALL', 'protect');
+
 ?>
diff --git a/includes/EditComment.php b/includes/EditComment.php
new file mode 100644 (file)
index 0000000..6edb39d
--- /dev/null
@@ -0,0 +1,321 @@
+<?php
+
+# Manages a page to edit a Revision Comment (Summary) and the "Minor change" flag.
+class EditComment {
+       var $mArticle, $mTitle, $origAction, $expiry, $fudgedExpiry; # from initializer
+       var $revisionID, $returnTo, $returnToAction, $returnToTarget; # from HTTP parameters
+       var $commentValue, $revisionTimeStamp, $revisionMinor, $revisionUID; # from article, etc.
+
+       function EditComment( $article, $action ) {
+               global $wgUser, $wgUserEditCommentTimeout;
+       
+               $this->mArticle =& $article;
+               $this->mTitle =& $article->mTitle;
+               $this->origAction = $action;
+               $this->commentValue = "";
+               
+               # Come up with an earliest time that a user may edit an article.
+               $this->expiry = $this->fudgedExpiry = '00000000000000'; # assume that any positive date is OK
+               if (! $wgUser->isAllowed(EDIT_COMMENT_ALL) && $wgUserEditCommentTimeout >= 0) {
+                       
+                       $this->expiry = wfTimestampPlus( wfTimestampNow(), -$wgUserEditCommentTimeout * 60 );
+               
+                       # If the user is allowed to change a time at all, add a little extra "fudge"
+                       # time to give the user the time to edit the change and save it.
+                       $fudgeTime = ($wgUserEditCommentTimeout) ? ($wgUserEditCommentTimeout + 2) : 
+                                       $wgUserEditCommentTimeout;
+                       $this->fudgedExpiry = wfTimestampPlus( wfTimestampNow(), -$fudgeTime * 60);
+               }
+       }
+       
+       function process() {
+               global $wgRequest;
+               global $wgUser, $wgOut, $wgScript;
+               global $wgAllowEditComments;
+               
+               # Pick up parameters that may be part of the URL.
+               $this->revisionID = $wgRequest->getInt( 'oldid' );
+               $this->returnTo = $wgRequest->getVal( 'returnto' );
+               $this->returnToAction = $wgRequest->getVal( 'returntoaction' );
+               $this->returnToTarget = $wgRequest->getVal( 'returntotarget' );
+               
+               # See if this is a submit.
+               $doSave = $wgRequest->getVal( 'wpSave' );
+               $doCancel = $wgRequest->getVal( 'wpCancel' );
+               
+               # We're either setting up the form for the first time, or picking existing form data.
+               if (! $doSave && ! $doCancel) {
+                       
+                       $this->getRevisionComment();
+                       
+                       # Error out if the user is not allowed to edit this comment.
+                       if ( ! $wgAllowEditComments || ! $wgUser->getID() ||
+                                ( ! $wgUser->isAllowed(EDIT_COMMENT_ALL) && $wgUser->getID() != $this->revisionUID )) {
+                               
+                               $wgOut->errorpage( "eceditsummary", "eccantdo" );
+                               return;
+                       }
+                       
+                       # Error out if the time the user had to edit this comment has expired.
+                       if ( $this->revisionTimeStamp < $this->expiry) {
+                               $wgOut->errorpage( "eceditsummary", "ecctimeexpired" );
+                               return;
+                       }
+                       
+                       $this->showForm( "" );
+               }
+               else {
+                       $this->revisionTimeStamp = $wgRequest->getText( 'wpTimestamp' );
+                       $this->revisionMinor = ( $wgRequest->getVal( 'wpMinorCheck' ) == "checked" ) ? 1 : 0;
+               }
+               
+               # Save the new comment, if requested.
+               if ($doSave) {
+                       $this->commentValue = $wgRequest->getText( 'wpComment' );
+                       
+                       # Error out if the time the user had to edit this comment has expired.
+                       if ( $this->revisionTimeStamp < $this->fudgedExpiry) {
+                               
+                               # Put the error message in the form to allow the user to copy their work.
+                               $this->showForm( wfMsg( "ecctimeexpired" ) );
+                               return;
+                       }
+                       
+                       # Note if something went wrong.
+                       $doWrong = ! $this->saveComment();
+               }
+               
+               # If Cancel, restore the original values.
+               if ($doCancel)
+                       $this->getRevisionComment();
+               
+               
+               # Let the user know an operation completed.
+               if ($doSave || $doCancel) {
+                       $sfmsg = "";
+                       if ($doSave) {
+                               if ($doWrong)
+                                       $sfmsg = wfMsg( "ecsavewrong" );
+                               else
+                                       $sfmsg = wfMsg( "ecsaveok" );
+                       }
+                       if ($doCancel)          # (shouldn't have both these messages.)
+                               $sfmsg .= wfMsg( "eccanceled" );
+                       
+                       $this->showForm( $sfmsg );
+               }
+       }
+       
+       # Show the Edit Comment (Summary) form. If $rsltMsg == "" the form is being
+       # displayed for the first time, with buttons. Otherwise it is being shown
+       # to provide confirmation and exit the process. Present a 'returnTo' link
+       # in that case.
+       function showForm( $rsltMsg )
+       {
+               global $wgOut, $wgUser, $wgLang;
+               global $wgRequest;
+               
+               $rt = $ra = $rtt = $buttonRow = '';
+               
+               $wgOut->setArticleFlag( false );
+
+               # The title is the article whose comments are being edited,
+               # the subtitle "Editing summary of " revision.
+               $wgOut->setPagetitle( $this->mTitle->getPrefixedText() );
+               if ($this->revisionID == 0)
+                       $wgOut->setSubtitle( wfMsg( "ecsubtitlerev0" ) );
+               else {
+                       $wgOut->setSubtitle( wfMsg( "ecsubtitle",
+                                                                $wgLang->timeanddate( $this->revisionTimeStamp, true ) ) );
+               }
+               $wgOut->addHTML( "<p>" . htmlspecialchars( wfMsg( "ecwarnings" ) ) . "</p>" );
+               # $wgOut->addWikiText( htmlspecialchars( wfMsg( "ecwarnings" ) ) );
+
+               $editcommentlabel = htmlspecialchars( wfMsg( "eccommentlabel" ) );
+               $editsubmit = htmlspecialchars( wfMsg( "ecsubmitbutton" ) );
+               $editcancel = htmlspecialchars( wfMsg( "eccancelbutton" ) );
+               $htmlcomment = htmlspecialchars( $this->commentValue );
+               # $titleObj = Title::makeTitle( NS_SPECIAL, "Blockip" );
+               # $action = $titleObj->escapeLocalURL( "action=editcomment" );
+               
+               if ($this->returnTo)
+                       $rt = "&returnto=" . $this->returnTo;
+               if ($this->returnToAction)
+                       $ra = "&returntoaction=" . $this->returnToAction;
+               if ($this->returnToTarget)
+                       $rtt = "&returntotarget=" . $this->returnToTarget;
+               $action = $this->mTitle->escapeLocalURL( "action=editcomment&oldid=" . $this->revisionID . $rt . $ra . $rtt);
+
+               # Either show the result message, or the Submit & Cancel buttons.
+               if ( "" != $rsltMsg ) {
+                       # $wgOut->setSubtitle( htmlspecialchars( wfMsg( "formerror" ) ) );
+                       $wgOut->addHTML( "<p class='error'>{$rsltMsg}</p>\n" );
+               }
+               else {
+                       $buttonRow = "
+               <tr>
+                       <td>&nbsp;</td>
+                       <td align=\"left\">
+                               <input tabindex='2' type='submit' name=\"wpSave\" value=\"{$editsubmit}\" />
+                               &nbsp;&nbsp;
+                               <input tabindex='3' type='submit' name=\"wpCancel\" value=\"{$editcancel}\" />
+                               <input type='hidden' name=\"wpTimestamp\" value=\"{$this->revisionTimeStamp}\" />
+                       </td>
+               </tr>";
+               }
+
+               $minorHeading = wfMsg( "minoredit" );
+               if ($this->revisionMinor == 1)
+                       $minorChecked = "checked";
+               else
+                       $minorChecked = "";
+               
+               $wgOut->addHTML( "
+<form id=\"editcomment\" method=\"post\" action=\"{$action}\">
+       <table border='0'>
+               <tr>
+                       <td align=\"right\">{$editcommentlabel}:</td>
+                       <td align=\"left\">
+                               <input tabindex='1' type='text' size='60' name=\"wpComment\" value=\"{$htmlcomment}\" />
+                       </td>
+               </tr>
+               <tr>
+                       <td>&nbsp;</td>
+                       <td>
+                               <input type='checkbox' name=\"wpMinorCheck\" value=\"checked\" {$minorChecked} />
+                               $minorHeading
+                       </td>
+               </tr>$buttonRow
+       </table>
+</form>\n" );
+
+               # Create a "return to" link, if appropriate.
+               if ( "" != $rsltMsg ) {
+                       if ($this->returnToAction)
+                               $rtmRa  = "action=" . $this->returnToAction;
+                       if ($this->returnToTarget) {
+                               if ($rtmRa)
+                                       $rtmRa  .= "&target=" . $this->returnToTarget;
+                               else
+                                       $rtmRa  = "target=" . $this->returnToTarget;
+                       }
+                       
+                       $wgOut->returnToMain( true, $this->returnTo, $rtmRa );
+               }
+
+       }
+       
+       # Save the required comment. Returns true if we performed a successful update.
+       # Do last microsecond check to insure someone isn't trying some shenanigans.
+       function saveComment()
+       {
+               global $wgOut, $wgIsMySQL, $wgIsPg, $wgUser;
+               
+               $usrChk = '';
+               
+               
+               # A user better be logged in.
+               if ( ! $wgUser->getID() )
+                       return false;
+               
+               if ($this->revisionID == 0) {
+                       
+                       # Pick up the old comment for the Recent Changes log.
+                       $oldComment = $this->mArticle->getComment();
+                       
+                       # Unless the user is a SysOp, they'd better be the person who made
+                       # the revision we're checking.
+                       if (! $wgUser->isAllowed(EDIT_COMMENT_ALL) )
+                               $usrChk = ' AND cur_user=' . $wgUser->getID();
+                       
+                       # We also want to make sure the date of the revision hasn't changed
+                       # "under our feet", as you will and that the expiry has not passed.
+                       $fname = "editComment";
+                       $sql = "UPDATE cur SET cur_comment='" .  wfStrencode( $this->commentValue ) . "', " .
+                         "cur_minor_edit=" . $this->revisionMinor . " " .
+                         "WHERE cur_id=" . $this->mArticle->getID() .
+                         " AND cur_timestamp='" . $this->revisionTimeStamp . "'" .
+                         " AND cur_timestamp>='" . $this->fudgedExpiry . "'" . $usrChk;
+                       $res = wfQuery( $sql, DB_WRITE, $fname );
+               }
+               else {
+                       
+                       # Pick up the old comment for the Recent Changes log.
+                       $fname = "editComment";
+                       $oldtable = $wgIsPg ? '"old"' : 'old';
+                       $sql = "SELECT old_comment FROM $oldtable " .
+                         "WHERE old_id={$this->revisionID}";
+                       $res = wfQuery( $sql, DB_READ, $fname );
+                       
+                       if ( 0 == wfNumRows( $res ) ) {
+                               return false;
+                       }
+                       $s = wfFetchObject( $res );
+                       $oldComment = $s->old_comment;
+                       
+                       # Unless the user is a SysOp, they'd better be the person who made
+                       # the revision we're checking.
+                       if (! $wgUser->isAllowed(EDIT_COMMENT_ALL) )
+                               $usrChk = ' AND old_user=' . $wgUser->getID();
+                       
+                       # Check that the expiry has not passed.
+                       $sql = "UPDATE $oldtable SET old_comment='" .  wfStrencode( $this->commentValue ) . "', " .
+                         "old_minor_edit=" . $this->revisionMinor . " " .
+                         "WHERE old_id={$this->revisionID}" .
+                         " AND old_timestamp>='" . $this->fudgedExpiry . "'" . $usrChk;
+                       $res = wfQuery( $sql, DB_WRITE, $fname );
+               }
+               
+               # Set a result based on whether any records got updated.
+               if( wfAffectedRows() == 0 ) {
+                       return false;
+               }
+               
+               # We need to invalidate the cache or the history page will not get refreshed.
+               $wgUser->invalidateCache();
+               $wgUser->saveSettings();                # Seems pretty drastic!
+               
+               # Log the comment change in Recent Changes.
+               RecentChange::notifyEditComment( wfTimestampNow(), $this->mTitle,
+                                                                                $this->revisionMinor, $wgUser, $this->commentValue, $oldComment,
+                                                                                $this->revisionID, $this->revisionTimeStamp);
+               
+               return true;                                    # We were successful.
+       }
+       
+       # Pick up the comment to be edited, as well as the revision time stamp and the
+       # user to make sure it can be edited.
+       function getRevisionComment()
+       {
+               global $wgOut, $wgIsMySQL, $wgIsPg;
+               
+               # If rev 0, we can use the article to get the data, otherwise get it ourselves.
+               if ($this->revisionID == 0) {
+                       $this->commentValue = $this->mArticle->getComment();
+                       $this->revisionTimeStamp = $this->mArticle->getTimestamp();
+                       $this->revisionMinor = $this->mArticle->getMinorEdit();
+                       $this->revisionUID = $this->mArticle->getUser();
+               }
+               else
+               {
+                       $fname = "editComment";
+                       $oldtable = $wgIsPg ? '"old"' : 'old';
+                       $sql = "SELECT old_comment,old_timestamp,old_minor_edit,old_user ".
+                         "FROM $oldtable " .
+                         "WHERE old_id={$this->revisionID}";
+                       $res = wfQuery( $sql, DB_READ, $fname );
+                       
+                       if ( 0 == wfNumRows( $res ) ) {
+                               return false;
+                       }
+                       $s = wfFetchObject( $res );
+                       $this->commentValue = $s->old_comment;
+                       $this->revisionTimeStamp = $s->old_timestamp;
+                       $this->revisionMinor = $s->old_minor_edit;
+                       $this->revisionUID = $s->old_user;
+                       wfFreeResult( $res );
+               }
+       }
+}
+
+?>
index 524ee08..e5f6f4c 100644 (file)
@@ -947,6 +947,14 @@ function wfTimestampNow() {
        return wfTimestamp( TS_MW, time() );
 }
 
+/**
+ * Convenience function; adds seconds to a MediaWiki timestamp.
+ * @return string
+ */
+function wfTimestampPlus ( $ts, $moreseconds ) {
+       return gmdate( 'YmdHis', wfTimestamp( TS_UNIX, $ts ) + $moreseconds );
+}
+
 /**
  * Sorting hack for MySQL 3, which doesn't use index sorts for DESC
  */
index 667cd78..08e316e 100644 (file)
@@ -529,7 +529,7 @@ class OutputPage {
                $this->mRedirect = '';
 
                $this->mBodytext = '';
-               $this->addHTML( '<p>' . wfMsg( $msg ) . "</p>\n" );
+               $this->addHTML( '<p class="error">' . wfMsg( $msg ) . "</p>\n" );
                $this->returnToMain( false );
 
                $this->output();
@@ -676,8 +676,9 @@ class OutputPage {
         * return from error messages or notes
         * @param $auto automatically redirect the user after 10 seconds
         * @param $returnto page title to return to. Default is Main Page.
+        * @param $query extra parameters to be added to the $returnto URL.
         */
-       function returnToMain( $auto = true, $returnto = NULL ) {
+       function returnToMain( $auto = true, $returnto = NULL, $query = NULL ) {
                global $wgUser, $wgOut, $wgRequest;
 
                if ( $returnto == NULL ) {
@@ -689,12 +690,12 @@ class OutputPage {
                if ( '' == $returnto ) {
                        $returnto = wfMsgForContent( 'mainpage' );
                }
-               $link = $sk->makeKnownLink( $returnto, '' );
+               $link = $sk->makeKnownLink( $returnto, '', $query );
 
                $r = wfMsg( 'returnto', $link );
                if ( $auto ) {
                        $titleObj = Title::newFromText( $returnto );
-                       $wgOut->addMeta( 'http:Refresh', '10;url=' . $titleObj->escapeFullURL() );
+                       $wgOut->addMeta( 'http:Refresh', '10;url=' . $titleObj->escapeFullURL( $query ) );
                }
                $wgOut->addHTML( "\n<p>$r</p>\n" );
        }
index f229792..1da58f7 100644 (file)
@@ -144,7 +144,8 @@ class PageHistory {
        }
 
        function historyLine( $ts, $u, $ut, $ns, $ttl, $oid, $c, $isminor, $counter = '' ) {
-               global $wgLang, $wgContLang;
+               global $wgLang, $wgContLang, $wgUser;
+               global $wgStylePath, $wgAllowEditComments, $wgUserEditCommentTimeout;
 
                static $message;
                if( !isset( $message ) ) {
@@ -199,6 +200,27 @@ class PageHistory {
                        $arbitrary .= '<input type="radio" name="diff" value="'.$oid.'" title="'.$message['selectnewerversionfordiff'].'"'.$checkmark.' />';
                }
                $s .= "({$curlink}) (!OLDID!{$oid}!) $arbitrary {$link} <span class='user'>{$ul}</span>";
+               
+               # Show an edit user comments icon if conditions are met.
+               # Option must be on, user logged in, user edited comment or a sysop,
+               # and the article must be recent enough.
+               if ( $wgAllowEditComments && $wgUser->getID() && 
+                    ($u == $wgUser->getID() || $wgUser->isAllowed(EDIT_COMMENT_ALL)) &&
+                    ($wgUser->isAllowed(EDIT_COMMENT_ALL) || $wgUserEditCommentTimeout < 0 || 
+                     $ts >= wfTimestampPlus( wfTimestampNow(), -$wgUserEditCommentTimeout * 60)) ) {
+                       
+                       $tooltip = wfMsg( "ectooltip" );
+                       $rt = $this->mTitle->getPrefixedURL();
+                       $rt = $this->mSkin->makeKnownLinkObj( $this->mTitle, "<img src=\"".$wgStylePath."/common/images/editcomment_icon.gif\" alt=\"{$tooltip}\" />",
+                         "action=editcomment&oldid={$oid}&returnto={$rt}&returntoaction=history" );
+                       
+                       # ***** Kludge ****
+                       # Swap out the tool tip created by makeKnownLink() with one appropriate for this link.
+                       $rt = preg_replace( '/title\=\"[^\"]*\"/', 'title="' . $tooltip . '"', $rt);
+                       
+                       $s .= $rt;
+               }
+               
                $s .= $isminor ? ' <span class="minor">'.$message['minoreditletter'].'</span>': '' ;
 
 
index 248cb2f..0a79228 100644 (file)
@@ -12,6 +12,7 @@ define( 'RC_NEW', 1);
 define( 'RC_MOVE', 2);
 define( 'RC_LOG', 3);
 define( 'RC_MOVE_OVER_REDIRECT', 4);
+define( "RC_EDIT_COMMENT", 5);
 
 
 /**
@@ -331,6 +332,46 @@ class RecentChange
                );
                $rc->save();
        }
+       
+       # Makes an entry in the database corresponding to editing a comment.
+       # Note: This code saves the old comment in 'rc_moved_to_title', which is only used
+       #       for logging move operations.
+       /*static*/ function notifyEditComment( $timestamp, &$title, $minor, &$user, $comment, $oldComment,
+               $revId, $lastTimestamp, $ip = '' ) 
+       {
+               if ( !$ip ) {
+                       global $wgIP;
+                       $ip = empty( $wgIP ) ? '' : $wgIP;
+               }
+               
+               $rc = new RecentChange;
+               $rc->mAttribs = array(
+                       'rc_timestamp'  => $timestamp,
+                       'rc_cur_time'   => $timestamp,
+                       'rc_namespace'  => $title->getNamespace(),
+                       'rc_title'      => $title->getDBkey(),
+                       'rc_type'       => RC_EDIT_COMMENT,
+                       'rc_minor'      => $minor ? 1 : 0,
+                       'rc_cur_id'     => $title->getArticleID(),
+                       'rc_user'       => $user->getID(),
+                       'rc_user_text'  => $user->getName(),
+                       'rc_comment'    => $comment,
+                       'rc_this_oldid' => $revId,
+                       'rc_last_oldid' => 0,
+                       'rc_bot'        => 0,
+                       'rc_moved_to_ns'        => 0,
+                       'rc_moved_to_title'     => $oldComment,
+                       'rc_ip' => $ip,
+                       'rc_patrolled' => 1,
+                       'rc_new'        => 0 # obsolete
+               );
+               
+               $rc->mExtra =  array(
+                       'prefixedDBkey' => $title->getPrefixedDBkey(),
+                       'lastTimestamp' => $lastTimestamp
+               );
+               $rc->save();
+       }
 
        # Initialises the members of this object from a mysql row object
        function loadFromRow( $row )
index 0088532..c32996f 100644 (file)
@@ -157,7 +157,7 @@ function wfSpecialContributions( $par = '' ) {
 
                        $obj1 = $dbr->fetchObject( $res1 );
                        $topmark = true;
-                       $oldid = false;
+                       $oldid = 0;
                        --$nCur;
                } else {
                        $ns = $obj2->old_namespace;
@@ -174,7 +174,7 @@ function wfSpecialContributions( $par = '' ) {
                        --$nOld;
                }
                if( $n >= $offset )
-                       ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, ( $me > 0), $isnew, $usertext, $oldid );
+                       ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, ( $me > 0), $isnew, $usertext, $oldid, $id );
        }
        $wgOut->addHTML( "</ul>\n" );
 
@@ -207,11 +207,13 @@ function wfSpecialContributions( $par = '' ) {
  * 
  * @todo This would probably look a lot nicer in a table.
  */
-function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew, $target, $oldid ) {
+function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew, $target, $oldid, $id ) {
        $fname = 'ucListEdit';
        wfProfileIn( $fname );
        
        global $wgLang, $wgOut, $wgUser, $wgRequest;
+       global $wgStylePath, $wgAllowEditComments, $wgUserEditCommentTimeout;
+       
        static $messages;
        if( !isset( $messages ) ) {
                foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg ) {
@@ -254,8 +256,28 @@ function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew, $t
        } else {
                $mflag = '';
        }
+       
+       # Show an edit user comments icon if conditions are met.
+       # Option must be on, user logged in, user these contributions are for or a sysop,
+       # and the article must be recent enough.
+       if ( $wgAllowEditComments && $wgUser->getID() &&
+                ($id == $wgUser->getID() || $wgUser->isAllowed(EDIT_COMMENT_ALL)) &&
+                ($wgUser->isAllowed(EDIT_COMMENT_ALL) || $wgUserEditCommentTimeout < 0 || 
+                 $ts >= wfTimestampPlus( wfTimestampNow(), -$wgUserEditCommentTimeout * 60)) ) {
+               
+               $tooltip = wfMsg( "ectooltip" );
+               $rt = $sk->makeKnownLinkObj( $page, "<img src=\"".$wgStylePath."/common/images/editcomment_icon.gif\" alt=\"{$tooltip}\" />",
+                 "action=editcomment&oldid={$oldid}&returnto=Special:Contributions&returntotarget=$target" );
+               
+               # ***** Kludge ****
+               # Swap out the tool tip created by makeKnownLink() with one appropriate for this link.
+               $rt = preg_replace( '/title\=\"[^\"]*\"/', 'title="' . $tooltip . '"', $rt);
+       }
+       else {
+               $rt = '';
+       }
 
-       $wgOut->addHTML( "<li>{$d} {$histlink} {$difftext} {$mflag} {$link} {$comment} {$topmarktext}</li>\n" );
+       $wgOut->addHTML( "<li>{$d} {$histlink} {$difftext} {$link} {$rt} {$mflag} {$comment} {$topmarktext}</li>\n" );
        wfProfileOut( $fname );
 }
 
index 5486408..6196aca 100644 (file)
--- a/index.php
+++ b/index.php
@@ -171,6 +171,11 @@ if( !is_null( $search ) && $search !== '' ) {
                        $raw = new RawPage( $wgArticle );
                        $raw->view();
                        break;
+               case "editcomment":
+                       require_once( "includes/EditComment.php" );
+                       $ecom = new EditComment( $wgArticle, $action );
+                       $ecom->process();
+                       break;
                case "purge":
                        wfPurgeSquidServers(array($wgTitle->getInternalURL()));
                        $wgOut->setSquidMaxage( $wgSquidMaxage );
index 87c67c3..a1aafca 100644 (file)
@@ -1239,6 +1239,25 @@ See [[Special:Log/delete]] for a record of recent deletions and restorations.",
 'uctop'         => ' (top)' ,
 'newbies'       => 'newbies',
 
+# Edit comments
+#
+'eceditsummary'        => 'Edit Summary',
+'ecsubtitle'   => 'Editing summary for revision of $1',
+'ecsubtitlerev0' => 'Editing summary for current revision',
+'ecwarnings'   => 'Warnings: There is no revert or history for summaries. Changing summaries are permanent.
+Changes to summaries will not effect previous listings in Recent changes.',
+'eccommentlabel' => 'Summary',
+'ecsubmitbutton' => 'Change',
+'eccancelbutton' => 'Cancel',
+'ecsaveok'     => 'Save completed successfully.',
+'ecsavewrong'  => 'Save was not successful. Either the article was just modified, this change was unauthorized, or you made no changes.',
+'eccanceled'   => 'Cancel requested. Summary not changed.',
+'eccantdo'     => 'You are not allowed to edit the summary of this article.',
+'ecctimeexpired' => 'Sorry, the time period in which you could have edited this summary as expired.',
+'ectooltip'    => 'Edit summary',
+'eccommentchanged' => 'Summary of $1 changed',
+'ecrccommentformat' => 'was $1 now $2',
+
 # What links here
 #
 'whatlinkshere'        => 'What links here',
diff --git a/skins/common/images/editcomment_icon.gif b/skins/common/images/editcomment_icon.gif
new file mode 100644 (file)
index 0000000..e8e40a0
Binary files /dev/null and b/skins/common/images/editcomment_icon.gif differ