MediaWiki
REL1_20
|
00001 <?php 00033 class LogFormatter { 00034 // Audience options for viewing usernames, comments, and actions 00035 const FOR_PUBLIC = 1; 00036 const FOR_THIS_USER = 2; 00037 00038 // Static-> 00039 00045 public static function newFromEntry( LogEntry $entry ) { 00046 global $wgLogActionsHandlers; 00047 $fulltype = $entry->getFullType(); 00048 $wildcard = $entry->getType() . '/*'; 00049 $handler = ''; 00050 00051 if ( isset( $wgLogActionsHandlers[$fulltype] ) ) { 00052 $handler = $wgLogActionsHandlers[$fulltype]; 00053 } elseif ( isset( $wgLogActionsHandlers[$wildcard] ) ) { 00054 $handler = $wgLogActionsHandlers[$wildcard]; 00055 } 00056 00057 if ( $handler !== '' && is_string( $handler ) && class_exists( $handler ) ) { 00058 return new $handler( $entry ); 00059 } 00060 00061 return new LegacyLogFormatter( $entry ); 00062 } 00063 00071 public static function newFromRow( $row ) { 00072 return self::newFromEntry( DatabaseLogEntry::newFromRow( $row ) ); 00073 } 00074 00075 // Nonstatic-> 00076 00078 protected $entry; 00079 00081 protected $audience = self::FOR_PUBLIC; 00082 00084 protected $linkFlood = false; 00085 00093 protected $plaintext = false; 00094 00095 protected $irctext = false; 00096 00097 protected function __construct( LogEntry $entry ) { 00098 $this->entry = $entry; 00099 $this->context = RequestContext::getMain(); 00100 } 00101 00106 public function setContext( IContextSource $context ) { 00107 $this->context = $context; 00108 } 00109 00116 public function setAudience( $audience ) { 00117 $this->audience = ( $audience == self::FOR_THIS_USER ) 00118 ? self::FOR_THIS_USER 00119 : self::FOR_PUBLIC; 00120 } 00121 00127 protected function canView( $field ) { 00128 if ( $this->audience == self::FOR_THIS_USER ) { 00129 return LogEventsList::userCanBitfield( 00130 $this->entry->getDeleted(), $field, $this->context->getUser() ); 00131 } else { 00132 return !$this->entry->isDeleted( $field ); 00133 } 00134 } 00135 00142 public function setShowUserToolLinks( $value ) { 00143 $this->linkFlood = $value; 00144 } 00145 00153 public function getPlainActionText() { 00154 $this->plaintext = true; 00155 $text = $this->getActionText(); 00156 $this->plaintext = false; 00157 return $text; 00158 } 00159 00166 public function getIRCActionComment() { 00167 $actionComment = $this->getIRCActionText(); 00168 $comment = $this->entry->getComment(); 00169 00170 if ( $comment != '' ) { 00171 if ( $actionComment == '' ) { 00172 $actionComment = $comment; 00173 } else { 00174 $actionComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $comment; 00175 } 00176 } 00177 00178 return $actionComment; 00179 } 00180 00187 public function getIRCActionText() { 00188 $this->plaintext = true; 00189 $this->irctext = true; 00190 00191 $entry = $this->entry; 00192 $parameters = $entry->getParameters(); 00193 // @see LogPage::actionText() 00194 // Text of title the action is aimed at. 00195 $target = $entry->getTarget()->getPrefixedText() ; 00196 $text = null; 00197 switch( $entry->getType() ) { 00198 case 'move': 00199 switch( $entry->getSubtype() ) { 00200 case 'move': 00201 $movesource = $parameters['4::target']; 00202 $text = wfMessage( '1movedto2' ) 00203 ->rawParams( $target, $movesource )->inContentLanguage()->escaped(); 00204 break; 00205 case 'move_redir': 00206 $movesource = $parameters['4::target']; 00207 $text = wfMessage( '1movedto2_redir' ) 00208 ->rawParams( $target, $movesource )->inContentLanguage()->escaped(); 00209 break; 00210 case 'move-noredirect': 00211 break; 00212 case 'move_redir-noredirect': 00213 break; 00214 } 00215 break; 00216 00217 case 'delete': 00218 switch( $entry->getSubtype() ) { 00219 case 'delete': 00220 $text = wfMessage( 'deletedarticle' ) 00221 ->rawParams( $target )->inContentLanguage()->escaped(); 00222 break; 00223 case 'restore': 00224 $text = wfMessage( 'undeletedarticle' ) 00225 ->rawParams( $target )->inContentLanguage()->escaped(); 00226 break; 00227 //case 'revision': // Revision deletion 00228 //case 'event': // Log deletion 00229 // see https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/LogPage.php?&pathrev=97044&r1=97043&r2=97044 00230 //default: 00231 } 00232 break; 00233 00234 case 'patrol': 00235 // https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/PatrolLog.php?&pathrev=97495&r1=97494&r2=97495 00236 // Create a diff link to the patrolled revision 00237 if ( $entry->getSubtype() === 'patrol' ) { 00238 $diffLink = htmlspecialchars( 00239 wfMessage( 'patrol-log-diff', $parameters['4::curid'] ) 00240 ->inContentLanguage()->text() ); 00241 $text = wfMessage( 'patrol-log-line', $diffLink, "[[$target]]", "" ) 00242 ->inContentLanguage()->text(); 00243 } else { 00244 // broken?? 00245 } 00246 break; 00247 00248 case 'protect': 00249 switch( $entry->getSubtype() ) { 00250 case 'protect': 00251 $text = wfMessage( 'protectedarticle' ) 00252 ->rawParams( $target . ' ' . $parameters[0] )->inContentLanguage()->escaped(); 00253 break; 00254 case 'unprotect': 00255 $text = wfMessage( 'unprotectedarticle' ) 00256 ->rawParams( $target )->inContentLanguage()->escaped(); 00257 break; 00258 case 'modify': 00259 $text = wfMessage( 'modifiedarticleprotection' ) 00260 ->rawParams( $target . ' ' . $parameters[0] )->inContentLanguage()->escaped(); 00261 break; 00262 } 00263 break; 00264 00265 case 'newusers': 00266 switch( $entry->getSubtype() ) { 00267 case 'newusers': 00268 case 'create': 00269 $text = wfMessage( 'newuserlog-create-entry' ) 00270 ->inContentLanguage()->escaped(); 00271 break; 00272 case 'create2': 00273 $text = wfMessage( 'newuserlog-create2-entry' ) 00274 ->rawParams( $target )->inContentLanguage()->escaped(); 00275 break; 00276 case 'autocreate': 00277 $text = wfMessage( 'newuserlog-autocreate-entry' ) 00278 ->inContentLanguage()->escaped(); 00279 break; 00280 } 00281 break; 00282 00283 case 'upload': 00284 switch( $entry->getSubtype() ) { 00285 case 'upload': 00286 $text = wfMessage( 'uploadedimage' ) 00287 ->rawParams( $target )->inContentLanguage()->escaped(); 00288 break; 00289 case 'overwrite': 00290 $text = wfMessage( 'overwroteimage' ) 00291 ->rawParams( $target )->inContentLanguage()->escaped(); 00292 break; 00293 } 00294 break; 00295 00296 00297 // case 'suppress' --private log -- aaron (sign your messages so we know who to blame in a few years :-D) 00298 // default: 00299 } 00300 if( is_null( $text ) ) { 00301 $text = $this->getPlainActionText(); 00302 } 00303 00304 $this->plaintext = false; 00305 $this->irctext = false; 00306 return $text; 00307 } 00308 00313 public function getActionText() { 00314 if ( $this->canView( LogPage::DELETED_ACTION ) ) { 00315 $element = $this->getActionMessage(); 00316 if ( $element instanceof Message ) { 00317 $element = $this->plaintext ? $element->text() : $element->escaped(); 00318 } 00319 if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) { 00320 $element = $this->styleRestricedElement( $element ); 00321 } 00322 } else { 00323 $performer = $this->getPerformerElement() . $this->msg( 'word-separator' )->text(); 00324 $element = $performer . $this->getRestrictedElement( 'rev-deleted-event' ); 00325 } 00326 00327 return $element; 00328 } 00329 00336 protected function getActionMessage() { 00337 $message = $this->msg( $this->getMessageKey() ); 00338 $message->params( $this->getMessageParameters() ); 00339 return $message; 00340 } 00341 00349 protected function getMessageKey() { 00350 $type = $this->entry->getType(); 00351 $subtype = $this->entry->getSubtype(); 00352 00353 return "logentry-$type-$subtype"; 00354 } 00355 00361 public function getActionLinks() { 00362 return ''; 00363 } 00364 00370 protected function extractParameters() { 00371 $entry = $this->entry; 00372 $params = array(); 00373 00374 if ( $entry->isLegacy() ) { 00375 foreach ( $entry->getParameters() as $index => $value ) { 00376 $params[$index + 3] = $value; 00377 } 00378 } 00379 00380 // Filter out parameters which are not in format #:foo 00381 foreach ( $entry->getParameters() as $key => $value ) { 00382 if ( strpos( $key, ':' ) === false ) continue; 00383 list( $index, $type, $name ) = explode( ':', $key, 3 ); 00384 $params[$index - 1] = $value; 00385 } 00386 00387 /* Message class doesn't like non consecutive numbering. 00388 * Fill in missing indexes with empty strings to avoid 00389 * incorrect renumbering. 00390 */ 00391 if ( count( $params ) ) { 00392 $max = max( array_keys( $params ) ); 00393 for ( $i = 4; $i < $max; $i++ ) { 00394 if ( !isset( $params[$i] ) ) { 00395 $params[$i] = ''; 00396 } 00397 } 00398 } 00399 return $params; 00400 } 00401 00411 protected function getMessageParameters() { 00412 if ( isset( $this->parsedParameters ) ) { 00413 return $this->parsedParameters; 00414 } 00415 00416 $entry = $this->entry; 00417 $params = $this->extractParameters(); 00418 $params[0] = Message::rawParam( $this->getPerformerElement() ); 00419 $params[1] = $entry->getPerformer()->getName(); 00420 $params[2] = Message::rawParam( $this->makePageLink( $entry->getTarget() ) ); 00421 00422 // Bad things happens if the numbers are not in correct order 00423 ksort( $params ); 00424 return $this->parsedParameters = $params; 00425 } 00426 00434 protected function makePageLink( Title $title = null, $parameters = array() ) { 00435 if ( !$this->plaintext ) { 00436 $link = Linker::link( $title, null, array(), $parameters ); 00437 } else { 00438 if ( !$title instanceof Title ) { 00439 throw new MWException( "Expected title, got null" ); 00440 } 00441 $link = '[[' . $title->getPrefixedText() . ']]'; 00442 } 00443 return $link; 00444 } 00445 00452 public function getPerformerElement() { 00453 if ( $this->canView( LogPage::DELETED_USER ) ) { 00454 $performer = $this->entry->getPerformer(); 00455 $element = $this->makeUserLink( $performer ); 00456 if ( $this->entry->isDeleted( LogPage::DELETED_USER ) ) { 00457 $element = $this->styleRestricedElement( $element ); 00458 } 00459 } else { 00460 $element = $this->getRestrictedElement( 'rev-deleted-user' ); 00461 } 00462 00463 return $element; 00464 } 00465 00470 public function getComment() { 00471 if ( $this->canView( LogPage::DELETED_COMMENT ) ) { 00472 $comment = Linker::commentBlock( $this->entry->getComment() ); 00473 // No hard coded spaces thanx 00474 $element = ltrim( $comment ); 00475 if ( $this->entry->isDeleted( LogPage::DELETED_COMMENT ) ) { 00476 $element = $this->styleRestricedElement( $element ); 00477 } 00478 } else { 00479 $element = $this->getRestrictedElement( 'rev-deleted-comment' ); 00480 } 00481 00482 return $element; 00483 } 00484 00490 protected function getRestrictedElement( $message ) { 00491 if ( $this->plaintext ) { 00492 return $this->msg( $message )->text(); 00493 } 00494 00495 $content = $this->msg( $message )->escaped(); 00496 $attribs = array( 'class' => 'history-deleted' ); 00497 return Html::rawElement( 'span', $attribs, $content ); 00498 } 00499 00505 protected function styleRestricedElement( $content ) { 00506 if ( $this->plaintext ) { 00507 return $content; 00508 } 00509 $attribs = array( 'class' => 'history-deleted' ); 00510 return Html::rawElement( 'span', $attribs, $content ); 00511 } 00512 00519 protected function msg( $key ) { 00520 return $this->context->msg( $key ); 00521 } 00522 00523 protected function makeUserLink( User $user ) { 00524 if ( $this->plaintext ) { 00525 $element = $user->getName(); 00526 } else { 00527 $element = Linker::userLink( 00528 $user->getId(), 00529 $user->getName() 00530 ); 00531 00532 if ( $this->linkFlood ) { 00533 $element .= Linker::userToolLinksRedContribs( 00534 $user->getId(), 00535 $user->getName(), 00536 $user->getEditCount() 00537 ); 00538 } 00539 } 00540 return $element; 00541 } 00542 00546 public function getPreloadTitles() { 00547 return array(); 00548 } 00549 00550 } 00551 00561 class LegacyLogFormatter extends LogFormatter { 00562 00572 private $comment = null; 00573 00581 private $revert = null; 00582 00583 public function getComment() { 00584 if ( $this->comment === null ) { 00585 $this->comment = parent::getComment(); 00586 } 00587 00588 // Make sure we execute the LogLine hook so that we immediately return 00589 // the correct value. 00590 if ( $this->revert === null ) { 00591 $this->getActionLinks(); 00592 } 00593 00594 return $this->comment; 00595 } 00596 00597 protected function getActionMessage() { 00598 $entry = $this->entry; 00599 $action = LogPage::actionText( 00600 $entry->getType(), 00601 $entry->getSubtype(), 00602 $entry->getTarget(), 00603 $this->plaintext ? null : $this->context->getSkin(), 00604 (array)$entry->getParameters(), 00605 !$this->plaintext // whether to filter [[]] links 00606 ); 00607 00608 $performer = $this->getPerformerElement(); 00609 if ( !$this->irctext ) { 00610 $action = $performer . $this->msg( 'word-separator' )->text() . $action; 00611 } 00612 00613 return $action; 00614 } 00615 00616 public function getActionLinks() { 00617 if ( $this->revert !== null ) { 00618 return $this->revert; 00619 } 00620 00621 if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) { 00622 return $this->revert = ''; 00623 } 00624 00625 $title = $this->entry->getTarget(); 00626 $type = $this->entry->getType(); 00627 $subtype = $this->entry->getSubtype(); 00628 00629 // Show unblock/change block link 00630 if ( ( $type == 'block' || $type == 'suppress' ) && ( $subtype == 'block' || $subtype == 'reblock' ) ) { 00631 if ( !$this->context->getUser()->isAllowed( 'block' ) ) { 00632 return ''; 00633 } 00634 00635 $links = array( 00636 Linker::linkKnown( 00637 SpecialPage::getTitleFor( 'Unblock', $title->getDBkey() ), 00638 $this->msg( 'unblocklink' )->escaped() 00639 ), 00640 Linker::linkKnown( 00641 SpecialPage::getTitleFor( 'Block', $title->getDBkey() ), 00642 $this->msg( 'change-blocklink' )->escaped() 00643 ) 00644 ); 00645 return $this->msg( 'parentheses' )->rawParams( 00646 $this->context->getLanguage()->pipeList( $links ) )->escaped(); 00647 // Show change protection link 00648 } elseif ( $type == 'protect' && ( $subtype == 'protect' || $subtype == 'modify' || $subtype == 'unprotect' ) ) { 00649 $links = array( 00650 Linker::link( $title, 00651 $this->msg( 'hist' )->escaped(), 00652 array(), 00653 array( 00654 'action' => 'history', 00655 'offset' => $this->entry->getTimestamp() 00656 ) 00657 ) 00658 ); 00659 if ( $this->context->getUser()->isAllowed( 'protect' ) ) { 00660 $links[] = Linker::linkKnown( 00661 $title, 00662 $this->msg( 'protect_change' )->escaped(), 00663 array(), 00664 array( 'action' => 'protect' ) 00665 ); 00666 } 00667 return $this->msg( 'parentheses' )->rawParams( 00668 $this->context->getLanguage()->pipeList( $links ) )->escaped(); 00669 // Show unmerge link 00670 } elseif( $type == 'merge' && $subtype == 'merge' ) { 00671 if ( !$this->context->getUser()->isAllowed( 'mergehistory' ) ) { 00672 return ''; 00673 } 00674 00675 $params = $this->extractParameters(); 00676 $revert = Linker::linkKnown( 00677 SpecialPage::getTitleFor( 'MergeHistory' ), 00678 $this->msg( 'revertmerge' )->escaped(), 00679 array(), 00680 array( 00681 'target' => $params[3], 00682 'dest' => $title->getPrefixedDBkey(), 00683 'mergepoint' => $params[4] 00684 ) 00685 ); 00686 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped(); 00687 } 00688 00689 // Do nothing. The implementation is handled by the hook modifiying the 00690 // passed-by-ref parameters. This also changes the default value so that 00691 // getComment() and getActionLinks() do not call them indefinitely. 00692 $this->revert = ''; 00693 00694 // This is to populate the $comment member of this instance so that it 00695 // can be modified when calling the hook just below. 00696 if ( $this->comment === null ) { 00697 $this->getComment(); 00698 } 00699 00700 $params = $this->entry->getParameters(); 00701 00702 wfRunHooks( 'LogLine', array( $type, $subtype, $title, $params, 00703 &$this->comment, &$this->revert, $this->entry->getTimestamp() ) ); 00704 00705 return $this->revert; 00706 } 00707 } 00708 00713 class MoveLogFormatter extends LogFormatter { 00714 public function getPreloadTitles() { 00715 $params = $this->extractParameters(); 00716 return array( Title::newFromText( $params[3] ) ); 00717 } 00718 00719 protected function getMessageKey() { 00720 $key = parent::getMessageKey(); 00721 $params = $this->getMessageParameters(); 00722 if ( isset( $params[4] ) && $params[4] === '1' ) { 00723 $key .= '-noredirect'; 00724 } 00725 return $key; 00726 } 00727 00728 protected function getMessageParameters() { 00729 $params = parent::getMessageParameters(); 00730 $oldname = $this->makePageLink( $this->entry->getTarget(), array( 'redirect' => 'no' ) ); 00731 $newname = $this->makePageLink( Title::newFromText( $params[3] ) ); 00732 $params[2] = Message::rawParam( $oldname ); 00733 $params[3] = Message::rawParam( $newname ); 00734 return $params; 00735 } 00736 00737 public function getActionLinks() { 00738 if ( $this->entry->isDeleted( LogPage::DELETED_ACTION ) // Action is hidden 00739 || $this->entry->getSubtype() !== 'move' 00740 || !$this->context->getUser()->isAllowed( 'move' ) ) 00741 { 00742 return ''; 00743 } 00744 00745 $params = $this->extractParameters(); 00746 $destTitle = Title::newFromText( $params[3] ); 00747 if ( !$destTitle ) { 00748 return ''; 00749 } 00750 00751 $revert = Linker::linkKnown( 00752 SpecialPage::getTitleFor( 'Movepage' ), 00753 $this->msg( 'revertmove' )->escaped(), 00754 array(), 00755 array( 00756 'wpOldTitle' => $destTitle->getPrefixedDBkey(), 00757 'wpNewTitle' => $this->entry->getTarget()->getPrefixedDBkey(), 00758 'wpReason' => $this->msg( 'revertmove' )->inContentLanguage()->text(), 00759 'wpMovetalk' => 0 00760 ) 00761 ); 00762 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped(); 00763 } 00764 } 00765 00770 class DeleteLogFormatter extends LogFormatter { 00771 protected function getMessageKey() { 00772 $key = parent::getMessageKey(); 00773 if ( in_array( $this->entry->getSubtype(), array( 'event', 'revision' ) ) ) { 00774 if ( count( $this->getMessageParameters() ) < 5 ) { 00775 return "$key-legacy"; 00776 } 00777 } 00778 return $key; 00779 } 00780 00781 protected function getMessageParameters() { 00782 if ( isset( $this->parsedParametersDeleteLog ) ) { 00783 return $this->parsedParametersDeleteLog; 00784 } 00785 00786 $params = parent::getMessageParameters(); 00787 $subtype = $this->entry->getSubtype(); 00788 if ( in_array( $subtype, array( 'event', 'revision' ) ) ) { 00789 if ( 00790 ($subtype === 'event' && count( $params ) === 6 ) || 00791 ($subtype === 'revision' && isset( $params[3] ) && $params[3] === 'revision' ) 00792 ) { 00793 $paramStart = $subtype === 'revision' ? 4 : 3; 00794 00795 $old = $this->parseBitField( $params[$paramStart+1] ); 00796 $new = $this->parseBitField( $params[$paramStart+2] ); 00797 list( $hid, $unhid, $extra ) = RevisionDeleter::getChanges( $new, $old ); 00798 $changes = array(); 00799 foreach ( $hid as $v ) { 00800 $changes[] = $this->msg( "$v-hid" )->plain(); 00801 } 00802 foreach ( $unhid as $v ) { 00803 $changes[] = $this->msg( "$v-unhid" )->plain(); 00804 } 00805 foreach ( $extra as $v ) { 00806 $changes[] = $this->msg( $v )->plain(); 00807 } 00808 $changeText = $this->context->getLanguage()->listToText( $changes ); 00809 00810 00811 $newParams = array_slice( $params, 0, 3 ); 00812 $newParams[3] = $changeText; 00813 $count = count( explode( ',', $params[$paramStart] ) ); 00814 $newParams[4] = $this->context->getLanguage()->formatNum( $count ); 00815 return $this->parsedParametersDeleteLog = $newParams; 00816 } else { 00817 return $this->parsedParametersDeleteLog = array_slice( $params, 0, 3 ); 00818 } 00819 } 00820 00821 return $this->parsedParametersDeleteLog = $params; 00822 } 00823 00824 protected function parseBitField( $string ) { 00825 // Input is like ofield=2134 or just the number 00826 if ( strpos( $string, 'field=' ) === 1 ) { 00827 list( , $field ) = explode( '=', $string ); 00828 return (int) $field; 00829 } else { 00830 return (int) $string; 00831 } 00832 } 00833 00834 public function getActionLinks() { 00835 $user = $this->context->getUser(); 00836 if ( !$user->isAllowed( 'deletedhistory' ) || $this->entry->isDeleted( LogPage::DELETED_ACTION ) ) { 00837 return ''; 00838 } 00839 00840 switch ( $this->entry->getSubtype() ) { 00841 case 'delete': // Show undelete link 00842 if( $user->isAllowed( 'undelete' ) ) { 00843 $message = 'undeletelink'; 00844 } else { 00845 $message = 'undeleteviewlink'; 00846 } 00847 $revert = Linker::linkKnown( 00848 SpecialPage::getTitleFor( 'Undelete' ), 00849 $this->msg( $message )->escaped(), 00850 array(), 00851 array( 'target' => $this->entry->getTarget()->getPrefixedDBkey() ) 00852 ); 00853 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped(); 00854 00855 case 'revision': // If an edit was hidden from a page give a review link to the history 00856 $params = $this->extractParameters(); 00857 if ( !isset( $params[3] ) || !isset( $params[4] ) ) { 00858 return ''; 00859 } 00860 00861 // Different revision types use different URL params... 00862 $key = $params[3]; 00863 // This is a CSV of the IDs 00864 $ids = explode( ',', $params[4] ); 00865 00866 $links = array(); 00867 00868 // If there's only one item, we can show a diff link 00869 if ( count( $ids ) == 1 ) { 00870 // Live revision diffs... 00871 if ( $key == 'oldid' || $key == 'revision' ) { 00872 $links[] = Linker::linkKnown( 00873 $this->entry->getTarget(), 00874 $this->msg( 'diff' )->escaped(), 00875 array(), 00876 array( 00877 'diff' => intval( $ids[0] ), 00878 'unhide' => 1 00879 ) 00880 ); 00881 // Deleted revision diffs... 00882 } elseif ( $key == 'artimestamp' || $key == 'archive' ) { 00883 $links[] = Linker::linkKnown( 00884 SpecialPage::getTitleFor( 'Undelete' ), 00885 $this->msg( 'diff' )->escaped(), 00886 array(), 00887 array( 00888 'target' => $this->entry->getTarget()->getPrefixedDBKey(), 00889 'diff' => 'prev', 00890 'timestamp' => $ids[0] 00891 ) 00892 ); 00893 } 00894 } 00895 00896 // View/modify link... 00897 $links[] = Linker::linkKnown( 00898 SpecialPage::getTitleFor( 'Revisiondelete' ), 00899 $this->msg( 'revdel-restore' )->escaped(), 00900 array(), 00901 array( 00902 'target' => $this->entry->getTarget()->getPrefixedText(), 00903 'type' => $key, 00904 'ids' => implode( ',', $ids ), 00905 ) 00906 ); 00907 00908 return $this->msg( 'parentheses' )->rawParams( 00909 $this->context->getLanguage()->pipeList( $links ) )->escaped(); 00910 00911 case 'event': // Hidden log items, give review link 00912 $params = $this->extractParameters(); 00913 if ( !isset( $params[3] ) ) { 00914 return ''; 00915 } 00916 // This is a CSV of the IDs 00917 $query = $params[3]; 00918 // Link to each hidden object ID, $params[1] is the url param 00919 $revert = Linker::linkKnown( 00920 SpecialPage::getTitleFor( 'Revisiondelete' ), 00921 $this->msg( 'revdel-restore' )->escaped(), 00922 array(), 00923 array( 00924 'target' => $this->entry->getTarget()->getPrefixedText(), 00925 'type' => 'logging', 00926 'ids' => $query 00927 ) 00928 ); 00929 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped(); 00930 default: 00931 return ''; 00932 } 00933 } 00934 } 00935 00940 class PatrolLogFormatter extends LogFormatter { 00941 protected function getMessageKey() { 00942 $key = parent::getMessageKey(); 00943 $params = $this->getMessageParameters(); 00944 if ( isset( $params[5] ) && $params[5] ) { 00945 $key .= '-auto'; 00946 } 00947 return $key; 00948 } 00949 00950 protected function getMessageParameters() { 00951 $params = parent::getMessageParameters(); 00952 00953 $target = $this->entry->getTarget(); 00954 $oldid = $params[3]; 00955 $revision = $this->context->getLanguage()->formatNum( $oldid, true ); 00956 00957 if ( $this->plaintext ) { 00958 $revlink = $revision; 00959 } elseif ( $target->exists() ) { 00960 $query = array( 00961 'oldid' => $oldid, 00962 'diff' => 'prev' 00963 ); 00964 $revlink = Linker::link( $target, htmlspecialchars( $revision ), array(), $query ); 00965 } else { 00966 $revlink = htmlspecialchars( $revision ); 00967 } 00968 00969 $params[3] = Message::rawParam( $revlink ); 00970 return $params; 00971 } 00972 } 00973 00978 class NewUsersLogFormatter extends LogFormatter { 00979 protected function getMessageParameters() { 00980 $params = parent::getMessageParameters(); 00981 if ( $this->entry->getSubtype() === 'create2' ) { 00982 if ( isset( $params[3] ) ) { 00983 $target = User::newFromId( $params[3] ); 00984 } else { 00985 $target = User::newFromName( $this->entry->getTarget()->getText(), false ); 00986 } 00987 $params[2] = Message::rawParam( $this->makeUserLink( $target ) ); 00988 $params[3] = $target->getName(); 00989 } 00990 return $params; 00991 } 00992 00993 public function getComment() { 00994 $timestamp = wfTimestamp( TS_MW, $this->entry->getTimestamp() ); 00995 if ( $timestamp < '20080129000000' ) { 00996 # Suppress $comment from old entries (before 2008-01-29), 00997 # not needed and can contain incorrect links 00998 return ''; 00999 } 01000 return parent::getComment(); 01001 } 01002 01003 public function getPreloadTitles() { 01004 if ( $this->entry->getSubtype() === 'create2' ) { 01005 //add the user talk to LinkBatch for the userLink 01006 return array( Title::makeTitle( NS_USER_TALK, $this->entry->getTarget()->getText() ) ); 01007 } 01008 return array(); 01009 } 01010 }