Merge "Fix separated login link so that create account and login are always next...
[lhc/web/wiklou.git] / includes / logging / LogFormatter.php
index 93f3f83..7586bb6 100644 (file)
@@ -109,24 +109,24 @@ class LogFormatter {
 
        /**
         * Set the visibility restrictions for displaying content.
-        * If set to public, and an item is deleted, then it will be replaced 
+        * If set to public, and an item is deleted, then it will be replaced
         * with a placeholder even if the context user is allowed to view it.
         * @param $audience integer self::FOR_THIS_USER or self::FOR_PUBLIC
         */
        public function setAudience( $audience ) {
                $this->audience = ( $audience == self::FOR_THIS_USER )
-                       ? self::FOR_THIS_USER 
+                       ? self::FOR_THIS_USER
                        : self::FOR_PUBLIC;
        }
 
        /**
         * Check if a log item can be displayed
         * @param $field integer LogPage::DELETED_* constant
-        * @return bool 
+        * @return bool
         */
        protected function canView( $field ) {
                if ( $this->audience == self::FOR_THIS_USER ) {
-                       return LogEventsList::userCanBitfield( 
+                       return LogEventsList::userCanBitfield(
                                $this->entry->getDeleted(), $field, $this->context->getUser() );
                } else {
                        return !$this->entry->isDeleted( $field );
@@ -171,7 +171,7 @@ class LogFormatter {
                        if ( $actionComment == '' ) {
                                $actionComment = $comment;
                        } else {
-                               $actionComment .= wfMsgForContent( 'colon-separator' ) . $comment;
+                               $actionComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $comment;
                        }
                }
 
@@ -187,12 +187,10 @@ class LogFormatter {
        public function getIRCActionText() {
                $this->plaintext = true;
                $this->irctext = true;
-               $text = $this->getActionText();
 
                $entry = $this->entry;
                $parameters = $entry->getParameters();
                // @see LogPage::actionText()
-               $msgOpts = array( 'parsemag', 'escape', 'replaceafter', 'content' );
                // Text of title the action is aimed at.
                $target = $entry->getTarget()->getPrefixedText() ;
                $text = null;
@@ -201,11 +199,13 @@ class LogFormatter {
                                switch( $entry->getSubtype() ) {
                                        case 'move':
                                                $movesource =  $parameters['4::target'];
-                                               $text = wfMsgExt( '1movedto2', $msgOpts, $target, $movesource );
+                                               $text = wfMessage( '1movedto2' )
+                                                       ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
                                        case 'move_redir':
                                                $movesource =  $parameters['4::target'];
-                                               $text = wfMsgExt( '1movedto2_redir', $msgOpts, $target, $movesource );
+                                               $text = wfMessage( '1movedto2_redir' )
+                                                       ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
                                        case 'move-noredirect':
                                                break;
@@ -217,10 +217,12 @@ class LogFormatter {
                        case 'delete':
                                switch( $entry->getSubtype() ) {
                                        case 'delete':
-                                               $text = wfMsgExt( 'deletedarticle', $msgOpts, $target );
+                                               $text = wfMessage( 'deletedarticle' )
+                                                       ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        case 'restore':
-                                               $text = wfMsgExt( 'undeletedarticle', $msgOpts, $target );
+                                               $text = wfMessage( 'undeletedarticle' )
+                                                       ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        //case 'revision': // Revision deletion
                                        //case 'event': // Log deletion
@@ -234,8 +236,10 @@ class LogFormatter {
                                // Create a diff link to the patrolled revision
                                if ( $entry->getSubtype() === 'patrol' ) {
                                        $diffLink = htmlspecialchars(
-                                               wfMsgForContent( 'patrol-log-diff', $parameters['4::curid'] ) );
-                                       $text = wfMsgForContent( 'patrol-log-line', $diffLink, "[[$target]]", "" );
+                                               wfMessage( 'patrol-log-diff', $parameters['4::curid'] )
+                                                       ->inContentLanguage()->text() );
+                                       $text = wfMessage( 'patrol-log-line', $diffLink, "[[$target]]", "" )
+                                               ->inContentLanguage()->text();
                                } else {
                                        // broken??
                                }
@@ -244,14 +248,17 @@ class LogFormatter {
                        case 'protect':
                                switch( $entry->getSubtype() ) {
                                case 'protect':
-                                       $text = wfMsgExt( 'protectedarticle', $msgOpts, $target . ' ' . $parameters[0] );
-                                               break;
+                                       $text = wfMessage( 'protectedarticle' )
+                                               ->rawParams( $target . ' ' . $parameters[0] )->inContentLanguage()->escaped();
+                                       break;
                                case 'unprotect':
-                                       $text = wfMsgExt( 'unprotectedarticle', $msgOpts, $target );
-                                               break;
+                                       $text = wfMessage( 'unprotectedarticle' )
+                                               ->rawParams( $target )->inContentLanguage()->escaped();
+                                       break;
                                case 'modify':
-                                       $text = wfMsgExt( 'modifiedarticleprotection', $msgOpts, $target . ' ' . $parameters[0] );
-                                               break;
+                                       $text = wfMessage( 'modifiedarticleprotection' )
+                                               ->rawParams( $target . ' ' . $parameters[0] )->inContentLanguage()->escaped();
+                                       break;
                                }
                                break;
 
@@ -259,13 +266,16 @@ class LogFormatter {
                                switch( $entry->getSubtype() ) {
                                        case 'newusers':
                                        case 'create':
-                                               $text = wfMsgExt( 'newuserlog-create-entry', $msgOpts /* no params */ );
+                                               $text = wfMessage( 'newuserlog-create-entry' )
+                                                       ->inContentLanguage()->escaped();
                                                break;
                                        case 'create2':
-                                               $text = wfMsgExt( 'newuserlog-create2-entry', $msgOpts, $target );
+                                               $text = wfMessage( 'newuserlog-create2-entry' )
+                                                       ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        case 'autocreate':
-                                               $text = wfMsgExt( 'newuserlog-autocreate-entry', $msgOpts /* no params */ );
+                                               $text = wfMessage( 'newuserlog-autocreate-entry' )
+                                                       ->inContentLanguage()->escaped();
                                                break;
                                }
                                break;
@@ -273,14 +283,16 @@ class LogFormatter {
                        case 'upload':
                                switch( $entry->getSubtype() ) {
                                        case 'upload':
-                                               $text = wfMsgExt( 'uploadedimage', $msgOpts, $target );
+                                               $text = wfMessage( 'uploadedimage' )
+                                                       ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        case 'overwrite':
-                                               $text = wfMsgExt( 'overwroteimage', $msgOpts, $target );
+                                               $text = wfMessage( 'overwroteimage' )
+                                                       ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                }
                                break;
-                       
+
 
                        // case 'suppress' --private log -- aaron  (sign your messages so we know who to blame in a few years :-D)
                        // default:
@@ -341,6 +353,15 @@ class LogFormatter {
                return "logentry-$type-$subtype";
        }
 
+       /**
+        * Returns extra links that comes after the action text, like "revert", etc.
+        *
+        * @return string
+        */
+       public function getActionLinks() {
+               return '';
+       }
+
        /**
         * Extracts the optional extra parameters for use in action messages.
         * The array indexes start from number 3.
@@ -509,11 +530,9 @@ class LogFormatter {
                        );
 
                        if ( $this->linkFlood ) {
-                               $element .= Linker::userToolLinks(
+                               $element .= Linker::userToolLinksRedContribs(
                                        $user->getId(),
                                        $user->getName(),
-                                       true, // Red if no edits
-                                       0, // Flags
                                        $user->getEditCount()
                                );
                        }
@@ -540,6 +559,41 @@ class LogFormatter {
  * @since 1.19
  */
 class LegacyLogFormatter extends LogFormatter {
+
+       /**
+        * Backward compatibility for extension changing the comment from
+        * the LogLine hook. This will be set by the first call on getComment(),
+        * then it might be modified by the hook when calling getActionLinks(),
+        * so that the modified value will be returned when calling getComment()
+        * a second time.
+        *
+        * @var string|null
+        */
+       private $comment = null;
+
+       /**
+        * Cache for the result of getActionLinks() so that it does not need to
+        * run multiple times depending on the order that getComment() and
+        * getActionLinks() are called.
+        *
+        * @var string|null
+        */
+       private $revert = null;
+
+       public function getComment() {
+               if ( $this->comment === null ) {
+                       $this->comment = parent::getComment();
+               }
+
+               // Make sure we execute the LogLine hook so that we immediately return
+               // the correct value.
+               if ( $this->revert === null ) {
+                       $this->getActionLinks();
+               }
+
+               return $this->comment;
+       }
+
        protected function getActionMessage() {
                $entry = $this->entry;
                $action = LogPage::actionText(
@@ -559,6 +613,97 @@ class LegacyLogFormatter extends LogFormatter {
                return $action;
        }
 
+       public function getActionLinks() {
+               if ( $this->revert !== null ) {
+                       return $this->revert;
+               }
+
+               if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) {
+                       return $this->revert = '';
+               }
+
+               $title = $this->entry->getTarget();
+               $type = $this->entry->getType();
+               $subtype = $this->entry->getSubtype();
+
+               // Show unblock/change block link
+               if ( ( $type == 'block' || $type == 'suppress' ) && ( $subtype == 'block' || $subtype == 'reblock' ) ) {
+                       if ( !$this->context->getUser()->isAllowed( 'block' ) ) {
+                               return '';
+                       }
+
+                       $links = array(
+                               Linker::linkKnown(
+                                       SpecialPage::getTitleFor( 'Unblock', $title->getDBkey() ),
+                                       $this->msg( 'unblocklink' )->escaped()
+                               ),
+                               Linker::linkKnown(
+                                       SpecialPage::getTitleFor( 'Block', $title->getDBkey() ),
+                                       $this->msg( 'change-blocklink' )->escaped()
+                               )
+                       );
+                       return $this->msg( 'parentheses' )->rawParams(
+                               $this->context->getLanguage()->pipeList( $links ) )->escaped();
+               // Show change protection link
+               } elseif ( $type == 'protect' && ( $subtype == 'protect' || $subtype == 'modify' || $subtype == 'unprotect' ) ) {
+                       $links = array(
+                               Linker::link( $title,
+                                       $this->msg( 'hist' )->escaped(),
+                                       array(),
+                                       array(
+                                               'action' => 'history',
+                                               'offset' => $this->entry->getTimestamp()
+                                       )
+                               )
+                       );
+                       if ( $this->context->getUser()->isAllowed( 'protect' ) ) {
+                               $links[] = Linker::linkKnown(
+                                       $title,
+                                       $this->msg( 'protect_change' )->escaped(),
+                                       array(),
+                                       array( 'action' => 'protect' )
+                               );
+                       }
+                       return $this->msg( 'parentheses' )->rawParams(
+                               $this->context->getLanguage()->pipeList( $links ) )->escaped();
+               // Show unmerge link
+               } elseif( $type == 'merge' && $subtype == 'merge' ) {
+                       if ( !$this->context->getUser()->isAllowed( 'mergehistory' ) ) {
+                               return '';
+                       }
+
+                       $params = $this->extractParameters();
+                       $revert = Linker::linkKnown(
+                               SpecialPage::getTitleFor( 'MergeHistory' ),
+                               $this->msg( 'revertmerge' )->escaped(),
+                               array(),
+                               array(
+                                       'target' => $params[3],
+                                       'dest' => $title->getPrefixedDBkey(),
+                                       'mergepoint' => $params[4]
+                               )
+                       );
+                       return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
+               }
+
+               // Do nothing. The implementation is handled by the hook modifiying the
+               // passed-by-ref parameters. This also changes the default value so that
+               // getComment() and getActionLinks() do not call them indefinitely.
+               $this->revert = '';
+
+               // This is to populate the $comment member of this instance so that it
+               // can be modified when calling the hook just below.
+               if ( $this->comment === null ) {
+                       $this->getComment();
+               }
+
+               $params = $this->entry->getParameters();
+
+               wfRunHooks( 'LogLine', array( $type, $subtype, $title, $params,
+                       &$this->comment, &$this->revert, $this->entry->getTimestamp() ) );
+
+               return $this->revert;
+       }
 }
 
 /**
@@ -588,6 +733,34 @@ class MoveLogFormatter extends LogFormatter {
                $params[3] = Message::rawParam( $newname );
                return $params;
        }
+
+       public function getActionLinks() {
+               if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden
+                       || $this->entry->getSubtype() !== 'move'
+                       || !$this->context->getUser()->isAllowed( 'move' ) )
+               {
+                       return '';
+               }
+
+               $params = $this->extractParameters();
+               $destTitle = Title::newFromText( $params[3] );
+               if ( !$destTitle ) {
+                       return '';
+               }
+
+               $revert = Linker::linkKnown(
+                       SpecialPage::getTitleFor( 'Movepage' ),
+                       $this->msg( 'revertmove' )->escaped(),
+                       array(),
+                       array(
+                               'wpOldTitle' => $destTitle->getPrefixedDBkey(),
+                               'wpNewTitle' => $this->entry->getTarget()->getPrefixedDBkey(),
+                               'wpReason'   => $this->msg( 'revertmove' )->inContentLanguage()->text(),
+                               'wpMovetalk' => 0
+                       )
+               );
+               return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
+       }
 }
 
 /**
@@ -657,6 +830,107 @@ class DeleteLogFormatter extends LogFormatter {
                        return (int) $string;
                }
        }
+
+       public function getActionLinks() {
+               $user = $this->context->getUser();
+               if ( !$user->isAllowed( 'deletedhistory' ) || $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) {
+                       return '';
+               }
+
+               switch ( $this->entry->getSubtype() ) {
+               case 'delete': // Show undelete link
+                       if( $user->isAllowed( 'undelete' ) ) {
+                               $message = 'undeletelink';
+                       } else {
+                               $message = 'undeleteviewlink';
+                       }
+                       $revert = Linker::linkKnown(
+                               SpecialPage::getTitleFor( 'Undelete' ),
+                               $this->msg( $message )->escaped(),
+                               array(),
+                               array( 'target' => $this->entry->getTarget()->getPrefixedDBkey() )
+                        );
+                       return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
+
+               case 'revision': // If an edit was hidden from a page give a review link to the history
+                       $params = $this->extractParameters();
+                       if ( !isset( $params[3] ) || !isset( $params[4] ) ) {
+                               return '';
+                       }
+
+                       // Different revision types use different URL params...
+                       $key = $params[3];
+                       // This is a CSV of the IDs
+                       $ids = explode( ',', $params[4] );
+
+                       $links = array();
+
+                       // If there's only one item, we can show a diff link
+                       if ( count( $ids ) == 1 ) {
+                               // Live revision diffs...
+                               if ( $key == 'oldid' || $key == 'revision' ) {
+                                       $links[] = Linker::linkKnown(
+                                               $this->entry->getTarget(),
+                                               $this->msg( 'diff' )->escaped(),
+                                               array(),
+                                               array(
+                                                       'diff' => intval( $ids[0] ),
+                                                       'unhide' => 1
+                                               )
+                                       );
+                               // Deleted revision diffs...
+                               } elseif ( $key == 'artimestamp' || $key == 'archive' ) {
+                                       $links[] = Linker::linkKnown(
+                                               SpecialPage::getTitleFor( 'Undelete' ),
+                                               $this->msg( 'diff' )->escaped(),
+                                               array(),
+                                               array(
+                                                       'target'    => $this->entry->getTarget()->getPrefixedDBKey(),
+                                                       'diff'      => 'prev',
+                                                       'timestamp' => $ids[0]
+                                               )
+                                       );
+                               }
+                       }
+
+                       // View/modify link...
+                       $links[] = Linker::linkKnown(
+                               SpecialPage::getTitleFor( 'Revisiondelete' ),
+                               $this->msg( 'revdel-restore' )->escaped(),
+                               array(),
+                               array(
+                                       'target' => $this->entry->getTarget()->getPrefixedText(),
+                                       'type' => $key,
+                                       'ids' => implode( ',', $ids ),
+                               )
+                       );
+
+                       return $this->msg( 'parentheses' )->rawParams(
+                               $this->context->getLanguage()->pipeList( $links ) )->escaped();
+
+               case 'event': // Hidden log items, give review link
+                       $params = $this->extractParameters();
+                       if ( !isset( $params[3] ) ) {
+                               return '';
+                       }
+                       // This is a CSV of the IDs
+                       $query = $params[3];
+                       // Link to each hidden object ID, $params[1] is the url param
+                       $revert = Linker::linkKnown(
+                               SpecialPage::getTitleFor( 'Revisiondelete' ),
+                               $this->msg( 'revdel-restore' )->escaped(),
+                               array(),
+                               array(
+                                       'target' => $this->entry->getTarget()->getPrefixedText(),
+                                       'type' => 'logging',
+                                       'ids' => $query
+                               )
+                       );
+                       return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
+               default:
+                       return '';
+               }
+       }
 }
 
 /**