00001 <?php
00002 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>, 2008 Aaron Schulz
00003 # http://www.mediawiki.org/
00004 #
00005 # This program is free software; you can redistribute it and/or modify
00006 # it under the terms of the GNU General Public License as published by
00007 # the Free Software Foundation; either version 2 of the License, or
00008 # (at your option) any later version.
00009 #
00010 # This program is distributed in the hope that it will be useful,
00011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 # GNU General Public License for more details.
00014 #
00015 # You should have received a copy of the GNU General Public License along
00016 # with this program; if not, write to the Free Software Foundation, Inc.,
00017 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 # http://www.gnu.org/copyleft/gpl.html
00019
00020 class LogEventsList {
00021 const NO_ACTION_LINK = 1;
00022
00023 private $skin;
00024 private $out;
00025 public $flags;
00026
00027 public function __construct( $skin, $out, $flags = 0 ) {
00028 $this->skin = $skin;
00029 $this->out = $out;
00030 $this->flags = $flags;
00031 $this->preCacheMessages();
00032 }
00033
00038 private function preCacheMessages() {
00039
00040 if( !isset( $this->message ) ) {
00041 $messages = array( 'revertmerge', 'protect_change', 'unblocklink', 'change-blocklink',
00042 'revertmove', 'undeletelink', 'revdel-restore', 'rev-delundel', 'hist', 'diff',
00043 'pipe-separator' );
00044 foreach( $messages as $msg ) {
00045 $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) );
00046 }
00047 }
00048 }
00049
00054 public function showHeader( $type ) {
00055 if( LogPage::isLogType( $type ) ) {
00056 $this->out->setPageTitle( LogPage::logName( $type ) );
00057 $this->out->addHTML( LogPage::logHeader( $type ) );
00058 }
00059 }
00060
00072 public function showOptions( $type = '', $user = '', $page = '', $pattern = '', $year = '',
00073 $month = '', $filter = null, $tagFilter='' )
00074 {
00075 global $wgScript, $wgMiserMode;
00076 $action = htmlspecialchars( $wgScript );
00077 $title = SpecialPage::getTitleFor( 'Log' );
00078 $special = htmlspecialchars( $title->getPrefixedDBkey() );
00079
00080 $tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter );
00081
00082 $this->out->addHTML( "<form action=\"$action\" method=\"get\"><fieldset>" .
00083 Xml::element( 'legend', array(), wfMsg( 'log' ) ) .
00084 Xml::hidden( 'title', $special ) . "\n" .
00085 $this->getTypeMenu( $type ) . "\n" .
00086 $this->getUserInput( $user ) . "\n" .
00087 $this->getTitleInput( $page ) . "\n" .
00088 ( !$wgMiserMode ? ($this->getTitlePattern( $pattern )."\n") : "" ) .
00089 "<p>" . Xml::dateMenu( $year, $month ) . "\n" .
00090 ( $tagSelector ? Xml::tags( 'p', null, implode( ' ', $tagSelector ) ) :'' ). "\n" .
00091 ( $filter ? "</p><p>".$this->getFilterLinks( $type, $filter )."\n" : "" ) . "\n" .
00092 Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . "</p>\n" .
00093 "</fieldset></form>"
00094 );
00095 }
00096
00097 private function getFilterLinks( $logType, $filter ) {
00098 global $wgTitle, $wgLang;
00099
00100 $messages = array( wfMsgHtml( 'show' ), wfMsgHtml( 'hide' ) );
00101
00102 $links = array();
00103 $hiddens = '';
00104 foreach( $filter as $type => $val ) {
00105 $hideVal = 1 - intval($val);
00106 $link = $this->skin->makeKnownLinkObj( $wgTitle, $messages[$hideVal],
00107 wfArrayToCGI( array( "hide_{$type}_log" => $hideVal ), $this->getDefaultQuery() )
00108 );
00109 $links[$type] = wfMsgHtml( "log-show-hide-{$type}", $link );
00110 $hiddens .= Xml::hidden( "hide_{$type}_log", $val ) . "\n";
00111 }
00112
00113 return '<small>'.$wgLang->pipeList( $links ) . '</small>' . $hiddens;
00114 }
00115
00116 private function getDefaultQuery() {
00117 if ( !isset( $this->mDefaultQuery ) ) {
00118 $this->mDefaultQuery = $_GET;
00119 unset( $this->mDefaultQuery['title'] );
00120 unset( $this->mDefaultQuery['dir'] );
00121 unset( $this->mDefaultQuery['offset'] );
00122 unset( $this->mDefaultQuery['limit'] );
00123 unset( $this->mDefaultQuery['order'] );
00124 unset( $this->mDefaultQuery['month'] );
00125 unset( $this->mDefaultQuery['year'] );
00126 }
00127 return $this->mDefaultQuery;
00128 }
00129
00134 private function getTypeMenu( $queryType ) {
00135 global $wgLogRestrictions, $wgUser;
00136
00137 $html = "<select name='type'>\n";
00138
00139 $validTypes = LogPage::validTypes();
00140 $typesByName = array();
00141
00142
00143 foreach( $validTypes as $type ) {
00144 $text = LogPage::logName( $type );
00145 $typesByName[$text] = $type;
00146 }
00147
00148
00149 ksort($typesByName);
00150
00151
00152 foreach( $typesByName as $text => $type ) {
00153 $selected = ($type == $queryType);
00154
00155 if ( isset($wgLogRestrictions[$type]) ) {
00156 if ( $wgUser->isAllowed( $wgLogRestrictions[$type] ) ) {
00157 $html .= Xml::option( $text, $type, $selected ) . "\n";
00158 }
00159 } else {
00160 $html .= Xml::option( $text, $type, $selected ) . "\n";
00161 }
00162 }
00163
00164 $html .= '</select>';
00165 return $html;
00166 }
00167
00172 private function getUserInput( $user ) {
00173 return Xml::inputLabel( wfMsg( 'specialloguserlabel' ), 'user', 'mw-log-user', 15, $user );
00174 }
00175
00180 private function getTitleInput( $title ) {
00181 return Xml::inputLabel( wfMsg( 'speciallogtitlelabel' ), 'page', 'mw-log-page', 20, $title );
00182 }
00183
00187 private function getTitlePattern( $pattern ) {
00188 return '<span style="white-space: nowrap">' .
00189 Xml::checkLabel( wfMsg( 'log-title-wildcard' ), 'pattern', 'pattern', $pattern ) .
00190 '</span>';
00191 }
00192
00193 public function beginLogEventsList() {
00194 return "<ul>\n";
00195 }
00196
00197 public function endLogEventsList() {
00198 return "</ul>\n";
00199 }
00200
00205 public function logLine( $row ) {
00206 global $wgLang, $wgUser, $wgContLang;
00207
00208 $title = Title::makeTitle( $row->log_namespace, $row->log_title );
00209 $classes = array( "mw-logline-{$row->log_type}" );
00210 $time = $wgLang->timeanddate( wfTimestamp(TS_MW, $row->log_timestamp), true );
00211
00212 if( self::isDeleted($row,LogPage::DELETED_USER) ) {
00213 $userLink = '<span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
00214 } else {
00215 $userLink = $this->skin->userLink( $row->log_user, $row->user_name ) .
00216 $this->skin->userToolLinks( $row->log_user, $row->user_name, true, 0, $row->user_editcount );
00217 }
00218
00219 if( self::isDeleted($row,LogPage::DELETED_COMMENT) ) {
00220 $comment = '<span class="history-deleted">' . wfMsgHtml('rev-deleted-comment') . '</span>';
00221 } else {
00222 $comment = $wgContLang->getDirMark() . $this->skin->commentBlock( $row->log_comment );
00223 }
00224
00225 $paramArray = LogPage::extractParams( $row->log_params );
00226 $revert = $del = '';
00227
00228 if( $wgUser->isAllowed( 'deleterevision' ) ) {
00229 $del = $this->getShowHideLinks( $row ) . ' ';
00230 }
00231
00232 if( ($this->flags & self::NO_ACTION_LINK) || ($row->log_deleted & LogPage::DELETED_ACTION) ) {
00233
00234 } else if( self::typeAction($row,'move','move','move') && !empty($paramArray[0]) ) {
00235 $destTitle = Title::newFromText( $paramArray[0] );
00236 if( $destTitle ) {
00237 $revert = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Movepage' ),
00238 $this->message['revertmove'],
00239 'wpOldTitle=' . urlencode( $destTitle->getPrefixedDBkey() ) .
00240 '&wpNewTitle=' . urlencode( $title->getPrefixedDBkey() ) .
00241 '&wpReason=' . urlencode( wfMsgForContent( 'revertmove' ) ) .
00242 '&wpMovetalk=0' ) . ')';
00243 }
00244
00245 } else if( self::typeAction($row,array('delete','suppress'),'delete','delete') ) {
00246 $revert = '(' . $this->skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Undelete' ),
00247 $this->message['undeletelink'], 'target='. urlencode( $title->getPrefixedDBkey() ) ) . ')';
00248
00249 } else if( self::typeAction($row,array('block','suppress'),array('block','reblock'),'block') ) {
00250 $revert = '(' .
00251 $this->skin->link( SpecialPage::getTitleFor( 'Ipblocklist' ),
00252 $this->message['unblocklink'],
00253 array(),
00254 array( 'action' => 'unblock', 'ip' => $row->log_title ),
00255 'known' )
00256 . $this->message['pipe-separator'] .
00257 $this->skin->link( SpecialPage::getTitleFor( 'Blockip', $row->log_title ),
00258 $this->message['change-blocklink'],
00259 array(), array(), 'known' ) .
00260 ')';
00261
00262 } else if( self::typeAction( $row, 'protect', array( 'modify', 'protect', 'unprotect' ) ) ) {
00263 $revert .= ' (' .
00264 $this->skin->link( $title,
00265 $this->message['hist'],
00266 array(),
00267 array( 'action' => 'history', 'offset' => $row->log_timestamp ) );
00268 if( $wgUser->isAllowed( 'protect' ) ) {
00269 $revert .= $this->message['pipe-separator'] .
00270 $this->skin->link( $title,
00271 $this->message['protect_change'],
00272 array(),
00273 array( 'action' => 'protect' ),
00274 'known' );
00275 }
00276 $revert .= ')';
00277
00278 } else if( self::typeAction($row,'merge','merge','mergehistory') ) {
00279 $merge = SpecialPage::getTitleFor( 'Mergehistory' );
00280 $revert = '(' . $this->skin->makeKnownLinkObj( $merge, $this->message['revertmerge'],
00281 wfArrayToCGI( array('target' => $paramArray[0], 'dest' => $title->getPrefixedDBkey(),
00282 'mergepoint' => $paramArray[1] ) ) ) . ')';
00283
00284 } else if( self::typeAction($row,array('delete','suppress'),'revision','deleterevision') ) {
00285 if( count($paramArray) == 2 ) {
00286 $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
00287
00288 $key = $paramArray[0];
00289
00290 $Ids = explode( ',', $paramArray[1] );
00291 $revParams = '';
00292 foreach( $Ids as $n => $id ) {
00293 $revParams .= '&' . urlencode($key) . '[]=' . urlencode($id);
00294 }
00295 $revert = array();
00296
00297 if( $key === 'oldid' && count($Ids) == 1 ) {
00298 $token = urlencode( $wgUser->editToken( intval($Ids[0]) ) );
00299 $revert[] = $this->skin->makeKnownLinkObj( $title, $this->message['diff'],
00300 'diff='.intval($Ids[0])."&unhide=1&token=$token" );
00301 }
00302
00303 $revert[] = $this->skin->makeKnownLinkObj( $revdel, $this->message['revdel-restore'],
00304 'target=' . $title->getPrefixedUrl() . $revParams );
00305 $revert = '(' . implode(' | ',$revert) . ')';
00306 }
00307
00308 } else if( self::typeAction($row,array('delete','suppress'),'event','deleterevision') ) {
00309 if( count($paramArray) == 1 ) {
00310 $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
00311 $Ids = explode( ',', $paramArray[0] );
00312
00313 $logParams = '';
00314 foreach( $Ids as $n => $id ) {
00315 $logParams .= '&logid[]=' . intval($id);
00316 }
00317 $revert = '(' . $this->skin->makeKnownLinkObj( $revdel, $this->message['revdel-restore'],
00318 'target=' . $title->getPrefixedUrl() . $logParams ) . ')';
00319 }
00320
00321 } else if( self::typeAction($row,'newusers','create2') ) {
00322 if( isset( $paramArray[0] ) ) {
00323 $revert = $this->skin->userToolLinks( $paramArray[0], $title->getDBkey(), true );
00324 } else {
00325 # Fall back to a blue contributions link
00326 $revert = $this->skin->userToolLinks( 1, $title->getDBkey() );
00327 }
00328 if( $time < '20080129000000' ) {
00329 # Suppress $comment from old entries (before 2008-01-29),
00330 # not needed and can contain incorrect links
00331 $comment = '';
00332 }
00333
00334 } else {
00335 wfRunHooks( 'LogLine', array( $row->log_type, $row->log_action, $title, $paramArray,
00336 &$comment, &$revert, $row->log_timestamp ) );
00337 }
00338
00339 if( self::isDeleted($row,LogPage::DELETED_ACTION) ) {
00340 $action = '<span class="history-deleted">' . wfMsgHtml('rev-deleted-event') . '</span>';
00341 } else {
00342 $action = LogPage::actionText( $row->log_type, $row->log_action, $title,
00343 $this->skin, $paramArray, true );
00344 }
00345
00346
00347 list($tagDisplay, $newClasses) = ChangeTags::formatSummaryRow( $row->ts_tags, 'logevent' );
00348 $classes = array_merge( $classes, $newClasses );
00349
00350 if( $revert != '' ) {
00351 $revert = '<span class="mw-logevent-actionlink">' . $revert . '</span>';
00352 }
00353
00354 return Xml::tags( 'li', array( "class" => implode( ' ', $classes ) ),
00355 $del . $time . ' ' . $userLink . ' ' . $action . ' ' . $comment . ' ' . $revert . " $tagDisplay" ) . "\n";
00356 }
00357
00362 private function getShowHideLinks( $row ) {
00363 $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
00364
00365 if( !self::userCan( $row, LogPage::DELETED_RESTRICTED ) ) {
00366 $del = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.$this->message['rev-delundel'].')' );
00367 } else if( $row->log_type == 'suppress' ) {
00368
00369 $del = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.$this->message['rev-delundel'].')' );
00370 } else {
00371 $target = SpecialPage::getTitleFor( 'Log', $row->log_type );
00372 $query = array( 'target' => $target->getPrefixedDBkey(),
00373 'logid[]' => $row->log_id
00374 );
00375 $del = $this->skin->revDeleteLink( $query, self::isDeleted( $row, LogPage::DELETED_RESTRICTED ) );
00376 }
00377 return $del;
00378 }
00379
00387 public static function typeAction( $row, $type, $action, $right='' ) {
00388 $match = is_array($type) ? in_array($row->log_type,$type) : $row->log_type == $type;
00389 if( $match ) {
00390 $match = is_array($action) ?
00391 in_array($row->log_action,$action) : $row->log_action == $action;
00392 if( $match && $right ) {
00393 global $wgUser;
00394 $match = $wgUser->isAllowed( $right );
00395 }
00396 }
00397 return $match;
00398 }
00399
00407 public static function userCan( $row, $field ) {
00408 if( ( $row->log_deleted & $field ) == $field ) {
00409 global $wgUser;
00410 $permission = ( $row->log_deleted & LogPage::DELETED_RESTRICTED ) == LogPage::DELETED_RESTRICTED
00411 ? 'suppressrevision'
00412 : 'deleterevision';
00413 wfDebug( "Checking for $permission due to $field match on $row->log_deleted\n" );
00414 return $wgUser->isAllowed( $permission );
00415 } else {
00416 return true;
00417 }
00418 }
00419
00425 public static function isDeleted( $row, $field ) {
00426 return ($row->log_deleted & $field) == $field;
00427 }
00428
00438 public static function showLogExtract( $out, $type='', $page='', $user='', $lim=0, $conds=array() ) {
00439 global $wgUser;
00440 # Insert list of top 50 or so items
00441 $loglist = new LogEventsList( $wgUser->getSkin(), $out, 0 );
00442 $pager = new LogPager( $loglist, $type, $user, $page, '', $conds );
00443 if( $lim > 0 ) $pager->mLimit = $lim;
00444 $logBody = $pager->getBody();
00445 if( $logBody ) {
00446 $out->addHTML(
00447 $loglist->beginLogEventsList() .
00448 $logBody .
00449 $loglist->endLogEventsList()
00450 );
00451 } else {
00452 $out->addWikiMsg( 'logempty' );
00453 }
00454 return $pager->getNumRows();
00455 }
00456
00463 public static function getExcludeClause( $db, $audience = 'public' ) {
00464 global $wgLogRestrictions, $wgUser;
00465
00466 $hiddenLogs = array();
00467
00468 foreach( $wgLogRestrictions as $logType => $right ) {
00469 if( $audience == 'public' || !$wgUser->isAllowed($right) ) {
00470 $safeType = $db->strencode( $logType );
00471 $hiddenLogs[] = $safeType;
00472 }
00473 }
00474 if( count($hiddenLogs) == 1 ) {
00475 return 'log_type != ' . $db->addQuotes( $hiddenLogs[0] );
00476 } elseif( $hiddenLogs ) {
00477 return 'log_type NOT IN (' . $db->makeList($hiddenLogs) . ')';
00478 }
00479 return false;
00480 }
00481 }
00482
00486 class LogPager extends ReverseChronologicalPager {
00487 private $type = '', $user = '', $title = '', $pattern = '';
00488 public $mLogEventsList;
00489
00501 public function __construct( $list, $type = '', $user = '', $title = '', $pattern = '',
00502 $conds = array(), $year = false, $month = false, $tagFilter = '' )
00503 {
00504 parent::__construct();
00505 $this->mConds = $conds;
00506
00507 $this->mLogEventsList = $list;
00508
00509 $this->limitType( $type );
00510 $this->limitUser( $user );
00511 $this->limitTitle( $title, $pattern );
00512 $this->getDateCond( $year, $month );
00513 $this->mTagFilter = $tagFilter;
00514 }
00515
00516 public function getDefaultQuery() {
00517 $query = parent::getDefaultQuery();
00518 $query['type'] = $this->type;
00519 $query['user'] = $this->user;
00520 $query['month'] = $this->mMonth;
00521 $query['year'] = $this->mYear;
00522 return $query;
00523 }
00524
00525 public function getFilterParams() {
00526 global $wgFilterLogTypes, $wgUser, $wgRequest;
00527 $filters = array();
00528 if( $this->type ) {
00529 return $filters;
00530 }
00531 foreach( $wgFilterLogTypes as $type => $default ) {
00532
00533 if( $type !== 'patrol' || $wgUser->useNPPatrol() ) {
00534 $hide = $wgRequest->getInt( "hide_{$type}_log", $default );
00535 $filters[$type] = $hide;
00536 if( $hide )
00537 $this->mConds[] = 'log_type != ' . $this->mDb->addQuotes( $type );
00538 }
00539 }
00540 return $filters;
00541 }
00542
00548 private function limitType( $type ) {
00549 global $wgLogRestrictions, $wgUser;
00550
00551 if( isset($wgLogRestrictions[$type]) && !$wgUser->isAllowed($wgLogRestrictions[$type]) ) {
00552 $type = '';
00553 }
00554
00555
00556 $audience = $type ? 'user' : 'public';
00557 $hideLogs = LogEventsList::getExcludeClause( $this->mDb, $audience );
00558 if( $hideLogs !== false ) {
00559 $this->mConds[] = $hideLogs;
00560 }
00561 if( $type ) {
00562 $this->type = $type;
00563 $this->mConds['log_type'] = $type;
00564 }
00565 }
00566
00571 private function limitUser( $name ) {
00572 if( $name == '' ) {
00573 return false;
00574 }
00575 $usertitle = Title::makeTitleSafe( NS_USER, $name );
00576 if( is_null($usertitle) ) {
00577 return false;
00578 }
00579
00580 $userid = User::idFromName( $name );
00581 if( !$userid ) {
00582
00583
00584 $this->mConds[] = "NULL";
00585 } else {
00586 global $wgUser;
00587 $this->mConds['log_user'] = $userid;
00588
00589 if( !$wgUser->isAllowed( 'suppressrevision' ) ) {
00590 $this->mConds[] = 'log_deleted & ' . LogPage::DELETED_USER . ' = 0';
00591 }
00592 $this->user = $usertitle->getText();
00593 }
00594 }
00595
00602 private function limitTitle( $page, $pattern ) {
00603 global $wgMiserMode, $wgUser;
00604
00605 $title = Title::newFromText( $page );
00606 if( strlen($page) == 0 || !$title instanceof Title )
00607 return false;
00608
00609 $this->title = $title->getPrefixedText();
00610 $ns = $title->getNamespace();
00611 # Using the (log_namespace, log_title, log_timestamp) index with a
00612 # range scan (LIKE) on the first two parts, instead of simple equality,
00613 # makes it unusable for sorting. Sorted retrieval using another index
00614 # would be possible, but then we might have to scan arbitrarily many
00615 # nodes of that index. Therefore, we need to avoid this if $wgMiserMode
00616 # is on.
00617 #
00618 # This is not a problem with simple title matches, because then we can
00619 # use the page_time index. That should have no more than a few hundred
00620 # log entries for even the busiest pages, so it can be safely scanned
00621 # in full to satisfy an impossible condition on user or similar.
00622 if( $pattern && !$wgMiserMode ) {
00623 # use escapeLike to avoid expensive search patterns like 't%st%'
00624 $safetitle = $this->mDb->escapeLike( $title->getDBkey() );
00625 $this->mConds['log_namespace'] = $ns;
00626 $this->mConds[] = "log_title LIKE '$safetitle%'";
00627 $this->pattern = $pattern;
00628 } else {
00629 $this->mConds['log_namespace'] = $ns;
00630 $this->mConds['log_title'] = $title->getDBkey();
00631 }
00632
00633 if( !$wgUser->isAllowed( 'suppressrevision' ) ) {
00634 $this->mConds[] = 'log_deleted & ' . LogPage::DELETED_ACTION . ' = 0';
00635 }
00636 }
00637
00638 public function getQueryInfo() {
00639 $this->mConds[] = 'user_id = log_user';
00640 # Don't use the wrong logging index
00641 if( $this->title || $this->pattern || $this->user ) {
00642 $index = array( 'USE INDEX' => array( 'logging' => array('page_time','user_time') ) );
00643 } else if( $this->type ) {
00644 $index = array( 'USE INDEX' => array( 'logging' => 'type_time' ) );
00645 } else {
00646 $index = array( 'USE INDEX' => array( 'logging' => 'times' ) );
00647 }
00648 $info = array(
00649 'tables' => array( 'logging', 'user' ),
00650 'fields' => array( 'log_type', 'log_action', 'log_user', 'log_namespace', 'log_title', 'log_params',
00651 'log_comment', 'log_id', 'log_deleted', 'log_timestamp', 'user_name', 'user_editcount' ),
00652 'conds' => $this->mConds,
00653 'options' => $index,
00654 'join_conds' => array( 'user' => array( 'INNER JOIN', 'user_id=log_user' ) ),
00655 );
00656
00657 ChangeTags::modifyDisplayQuery( $info['tables'], $info['fields'], $info['conds'],
00658 $info['join_conds'], $info['options'], $this->mTagFilter );
00659
00660 return $info;
00661 }
00662
00663 function getIndexField() {
00664 return 'log_timestamp';
00665 }
00666
00667 public function getStartBody() {
00668 wfProfileIn( __METHOD__ );
00669 # Do a link batch query
00670 if( $this->getNumRows() > 0 ) {
00671 $lb = new LinkBatch;
00672 while( $row = $this->mResult->fetchObject() ) {
00673 $lb->add( $row->log_namespace, $row->log_title );
00674 $lb->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) );
00675 $lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) );
00676 }
00677 $lb->execute();
00678 $this->mResult->seek( 0 );
00679 }
00680 wfProfileOut( __METHOD__ );
00681 return '';
00682 }
00683
00684 public function formatRow( $row ) {
00685 return $this->mLogEventsList->logLine( $row );
00686 }
00687
00688 public function getType() {
00689 return $this->type;
00690 }
00691
00692 public function getUser() {
00693 return $this->user;
00694 }
00695
00696 public function getPage() {
00697 return $this->title;
00698 }
00699
00700 public function getPattern() {
00701 return $this->pattern;
00702 }
00703
00704 public function getYear() {
00705 return $this->mYear;
00706 }
00707
00708 public function getMonth() {
00709 return $this->mMonth;
00710 }
00711
00712 public function getTagFilter() {
00713 return $this->mTagFilter;
00714 }
00715 }
00716
00721 class LogReader {
00722 var $pager;
00726 function __construct( $request ) {
00727 global $wgUser, $wgOut;
00728 wfDeprecated(__METHOD__);
00729 # Get parameters
00730 $type = $request->getVal( 'type' );
00731 $user = $request->getText( 'user' );
00732 $title = $request->getText( 'page' );
00733 $pattern = $request->getBool( 'pattern' );
00734 $year = $request->getIntOrNull( 'year' );
00735 $month = $request->getIntOrNull( 'month' );
00736 $tagFilter = $request->getVal( 'tagfilter' );
00737 # Don't let the user get stuck with a certain date
00738 $skip = $request->getText( 'offset' ) || $request->getText( 'dir' ) == 'prev';
00739 if( $skip ) {
00740 $year = '';
00741 $month = '';
00742 }
00743 # Use new list class to output results
00744 $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, 0 );
00745 $this->pager = new LogPager( $loglist, $type, $user, $title, $pattern, $year, $month, $tagFilter );
00746 }
00747
00752 public function hasRows() {
00753 return isset($this->pager) ? ($this->pager->getNumRows() > 0) : false;
00754 }
00755 }
00756
00761 class LogViewer {
00762 const NO_ACTION_LINK = 1;
00763
00767 var $reader;
00768
00774 function __construct( &$reader, $flags = 0 ) {
00775 global $wgUser;
00776 wfDeprecated(__METHOD__);
00777 $this->reader =& $reader;
00778 $this->reader->pager->mLogEventsList->flags = $flags;
00779 # Aliases for shorter code...
00780 $this->pager =& $this->reader->pager;
00781 $this->list =& $this->reader->pager->mLogEventsList;
00782 }
00783
00787 public function show() {
00788 # Set title and add header
00789 $this->list->showHeader( $pager->getType() );
00790 # Show form options
00791 $this->list->showOptions( $this->pager->getType(), $this->pager->getUser(), $this->pager->getPage(),
00792 $this->pager->getPattern(), $this->pager->getYear(), $this->pager->getMonth() );
00793 # Insert list
00794 $logBody = $this->pager->getBody();
00795 if( $logBody ) {
00796 $wgOut->addHTML(
00797 $this->pager->getNavigationBar() .
00798 $this->list->beginLogEventsList() .
00799 $logBody .
00800 $this->list->endLogEventsList() .
00801 $this->pager->getNavigationBar()
00802 );
00803 } else {
00804 $wgOut->addWikiMsg( 'logempty' );
00805 }
00806 }
00807
00814 public function showList( &$out ) {
00815 $logBody = $this->pager->getBody();
00816 if( $logBody ) {
00817 $out->addHTML(
00818 $this->list->beginLogEventsList() .
00819 $logBody .
00820 $this->list->endLogEventsList()
00821 );
00822 } else {
00823 $out->addWikiMsg( 'logempty' );
00824 }
00825 }
00826 }