MediaWiki
REL1_24
|
00001 <?php 00035 interface LogEntry { 00040 public function getType(); 00041 00046 public function getSubtype(); 00047 00052 public function getFullType(); 00053 00058 public function getParameters(); 00059 00064 public function getPerformer(); 00065 00070 public function getTarget(); 00071 00076 public function getTimestamp(); 00077 00082 public function getComment(); 00083 00088 public function getDeleted(); 00089 00094 public function isDeleted( $field ); 00095 } 00096 00101 abstract class LogEntryBase implements LogEntry { 00102 public function getFullType() { 00103 return $this->getType() . '/' . $this->getSubtype(); 00104 } 00105 00106 public function isDeleted( $field ) { 00107 return ( $this->getDeleted() & $field ) === $field; 00108 } 00109 00115 public function isLegacy() { 00116 return false; 00117 } 00118 } 00119 00124 class DatabaseLogEntry extends LogEntryBase { 00125 // Static-> 00126 00133 public static function getSelectQueryData() { 00134 $tables = array( 'logging', 'user' ); 00135 $fields = array( 00136 'log_id', 'log_type', 'log_action', 'log_timestamp', 00137 'log_user', 'log_user_text', 00138 'log_namespace', 'log_title', // unused log_page 00139 'log_comment', 'log_params', 'log_deleted', 00140 'user_id', 'user_name', 'user_editcount', 00141 ); 00142 00143 $joins = array( 00144 // IP's don't have an entry in user table 00145 'user' => array( 'LEFT JOIN', 'log_user=user_id' ), 00146 ); 00147 00148 return array( 00149 'tables' => $tables, 00150 'fields' => $fields, 00151 'conds' => array(), 00152 'options' => array(), 00153 'join_conds' => $joins, 00154 ); 00155 } 00156 00163 public static function newFromRow( $row ) { 00164 $row = (object)$row; 00165 if ( isset( $row->rc_logid ) ) { 00166 return new RCDatabaseLogEntry( $row ); 00167 } else { 00168 return new self( $row ); 00169 } 00170 } 00171 00172 // Non-static-> 00173 00175 protected $row; 00176 00178 protected $performer; 00179 00183 protected $legacy; 00184 00185 protected function __construct( $row ) { 00186 $this->row = $row; 00187 } 00188 00193 public function getId() { 00194 return (int)$this->row->log_id; 00195 } 00196 00201 protected function getRawParameters() { 00202 return $this->row->log_params; 00203 } 00204 00205 // LogEntryBase-> 00206 00207 public function isLegacy() { 00208 // This does the check 00209 $this->getParameters(); 00210 00211 return $this->legacy; 00212 } 00213 00214 // LogEntry-> 00215 00216 public function getType() { 00217 return $this->row->log_type; 00218 } 00219 00220 public function getSubtype() { 00221 return $this->row->log_action; 00222 } 00223 00224 public function getParameters() { 00225 if ( !isset( $this->params ) ) { 00226 $blob = $this->getRawParameters(); 00227 wfSuppressWarnings(); 00228 $params = unserialize( $blob ); 00229 wfRestoreWarnings(); 00230 if ( $params !== false ) { 00231 $this->params = $params; 00232 $this->legacy = false; 00233 } else { 00234 $this->params = $blob === '' ? array() : explode( "\n", $blob ); 00235 $this->legacy = true; 00236 } 00237 } 00238 00239 return $this->params; 00240 } 00241 00242 public function getPerformer() { 00243 if ( !$this->performer ) { 00244 $userId = (int)$this->row->log_user; 00245 if ( $userId !== 0 ) { // logged-in users 00246 if ( isset( $this->row->user_name ) ) { 00247 $this->performer = User::newFromRow( $this->row ); 00248 } else { 00249 $this->performer = User::newFromId( $userId ); 00250 } 00251 } else { // IP users 00252 $userText = $this->row->log_user_text; 00253 $this->performer = User::newFromName( $userText, false ); 00254 } 00255 } 00256 00257 return $this->performer; 00258 } 00259 00260 public function getTarget() { 00261 $namespace = $this->row->log_namespace; 00262 $page = $this->row->log_title; 00263 $title = Title::makeTitle( $namespace, $page ); 00264 00265 return $title; 00266 } 00267 00268 public function getTimestamp() { 00269 return wfTimestamp( TS_MW, $this->row->log_timestamp ); 00270 } 00271 00272 public function getComment() { 00273 return $this->row->log_comment; 00274 } 00275 00276 public function getDeleted() { 00277 return $this->row->log_deleted; 00278 } 00279 } 00280 00281 class RCDatabaseLogEntry extends DatabaseLogEntry { 00282 00283 public function getId() { 00284 return $this->row->rc_logid; 00285 } 00286 00287 protected function getRawParameters() { 00288 return $this->row->rc_params; 00289 } 00290 00291 // LogEntry-> 00292 00293 public function getType() { 00294 return $this->row->rc_log_type; 00295 } 00296 00297 public function getSubtype() { 00298 return $this->row->rc_log_action; 00299 } 00300 00301 public function getPerformer() { 00302 if ( !$this->performer ) { 00303 $userId = (int)$this->row->rc_user; 00304 if ( $userId !== 0 ) { 00305 $this->performer = User::newFromId( $userId ); 00306 } else { 00307 $userText = $this->row->rc_user_text; 00308 // Might be an IP, don't validate the username 00309 $this->performer = User::newFromName( $userText, false ); 00310 } 00311 } 00312 00313 return $this->performer; 00314 } 00315 00316 public function getTarget() { 00317 $namespace = $this->row->rc_namespace; 00318 $page = $this->row->rc_title; 00319 $title = Title::makeTitle( $namespace, $page ); 00320 00321 return $title; 00322 } 00323 00324 public function getTimestamp() { 00325 return wfTimestamp( TS_MW, $this->row->rc_timestamp ); 00326 } 00327 00328 public function getComment() { 00329 return $this->row->rc_comment; 00330 } 00331 00332 public function getDeleted() { 00333 return $this->row->rc_deleted; 00334 } 00335 } 00336 00342 class ManualLogEntry extends LogEntryBase { 00344 protected $type; 00345 00347 protected $subtype; 00348 00350 protected $parameters = array(); 00351 00353 protected $relations = array(); 00354 00356 protected $performer; 00357 00359 protected $target; 00360 00362 protected $timestamp; 00363 00365 protected $comment = ''; 00366 00368 protected $deleted; 00369 00371 protected $id; 00372 00381 public function __construct( $type, $subtype ) { 00382 $this->type = $type; 00383 $this->subtype = $subtype; 00384 } 00385 00402 public function setParameters( $parameters ) { 00403 $this->parameters = $parameters; 00404 } 00405 00413 public function setRelations( array $relations ) { 00414 $this->relations = $relations; 00415 } 00416 00424 public function setPerformer( User $performer ) { 00425 $this->performer = $performer; 00426 } 00427 00435 public function setTarget( Title $target ) { 00436 $this->target = $target; 00437 } 00438 00446 public function setTimestamp( $timestamp ) { 00447 $this->timestamp = $timestamp; 00448 } 00449 00457 public function setComment( $comment ) { 00458 $this->comment = $comment; 00459 } 00460 00468 public function setDeleted( $deleted ) { 00469 $this->deleted = $deleted; 00470 } 00471 00478 public function insert( IDatabase $dbw = null ) { 00479 global $wgContLang; 00480 00481 $dbw = $dbw ?: wfGetDB( DB_MASTER ); 00482 $id = $dbw->nextSequenceValue( 'logging_log_id_seq' ); 00483 00484 if ( $this->timestamp === null ) { 00485 $this->timestamp = wfTimestampNow(); 00486 } 00487 00488 # Trim spaces on user supplied text 00489 $comment = trim( $this->getComment() ); 00490 00491 # Truncate for whole multibyte characters. 00492 $comment = $wgContLang->truncate( $comment, 255 ); 00493 00494 $data = array( 00495 'log_id' => $id, 00496 'log_type' => $this->getType(), 00497 'log_action' => $this->getSubtype(), 00498 'log_timestamp' => $dbw->timestamp( $this->getTimestamp() ), 00499 'log_user' => $this->getPerformer()->getId(), 00500 'log_user_text' => $this->getPerformer()->getName(), 00501 'log_namespace' => $this->getTarget()->getNamespace(), 00502 'log_title' => $this->getTarget()->getDBkey(), 00503 'log_page' => $this->getTarget()->getArticleID(), 00504 'log_comment' => $comment, 00505 'log_params' => serialize( (array)$this->getParameters() ), 00506 ); 00507 if ( isset( $this->deleted ) ) { 00508 $data['log_deleted'] = $this->deleted; 00509 } 00510 00511 $dbw->insert( 'logging', $data, __METHOD__ ); 00512 $this->id = !is_null( $id ) ? $id : $dbw->insertId(); 00513 00514 $rows = array(); 00515 foreach ( $this->relations as $tag => $values ) { 00516 if ( !strlen( $tag ) ) { 00517 throw new MWException( "Got empty log search tag." ); 00518 } 00519 00520 if ( !is_array( $values ) ) { 00521 $values = array( $values ); 00522 } 00523 00524 foreach ( $values as $value ) { 00525 $rows[] = array( 00526 'ls_field' => $tag, 00527 'ls_value' => $value, 00528 'ls_log_id' => $this->id 00529 ); 00530 } 00531 } 00532 if ( count( $rows ) ) { 00533 $dbw->insert( 'log_search', $rows, __METHOD__, 'IGNORE' ); 00534 } 00535 00536 // Update any bloom filter cache 00537 $member = $this->getTarget()->getNamespace() . ':' . $this->getTarget()->getDBkey(); 00538 BloomCache::get( 'main' )->insert( wfWikiId(), 'TitleHasLogs', $member ); 00539 00540 return $this->id; 00541 } 00542 00549 public function getRecentChange( $newId = 0 ) { 00550 $formatter = LogFormatter::newFromEntry( $this ); 00551 $context = RequestContext::newExtraneousContext( $this->getTarget() ); 00552 $formatter->setContext( $context ); 00553 00554 $logpage = SpecialPage::getTitleFor( 'Log', $this->getType() ); 00555 $user = $this->getPerformer(); 00556 $ip = ""; 00557 if ( $user->isAnon() ) { 00558 /* 00559 * "MediaWiki default" and friends may have 00560 * no IP address in their name 00561 */ 00562 if ( IP::isIPAddress( $user->getName() ) ) { 00563 $ip = $user->getName(); 00564 } 00565 } 00566 00567 return RecentChange::newLogEntry( 00568 $this->getTimestamp(), 00569 $logpage, 00570 $user, 00571 $formatter->getPlainActionText(), 00572 $ip, 00573 $this->getType(), 00574 $this->getSubtype(), 00575 $this->getTarget(), 00576 $this->getComment(), 00577 serialize( (array)$this->getParameters() ), 00578 $newId, 00579 $formatter->getIRCActionComment() // Used for IRC feeds 00580 ); 00581 } 00582 00588 public function publish( $newId, $to = 'rcandudp' ) { 00589 $log = new LogPage( $this->getType() ); 00590 if ( $log->isRestricted() ) { 00591 return; 00592 } 00593 00594 $rc = $this->getRecentChange( $newId ); 00595 00596 if ( $to === 'rc' || $to === 'rcandudp' ) { 00597 $rc->save( 'pleasedontudp' ); 00598 } 00599 00600 if ( $to === 'udp' || $to === 'rcandudp' ) { 00601 $rc->notifyRCFeeds(); 00602 } 00603 } 00604 00605 // LogEntry-> 00606 00607 public function getType() { 00608 return $this->type; 00609 } 00610 00611 public function getSubtype() { 00612 return $this->subtype; 00613 } 00614 00615 public function getParameters() { 00616 return $this->parameters; 00617 } 00618 00622 public function getPerformer() { 00623 return $this->performer; 00624 } 00625 00629 public function getTarget() { 00630 return $this->target; 00631 } 00632 00633 public function getTimestamp() { 00634 $ts = $this->timestamp !== null ? $this->timestamp : wfTimestampNow(); 00635 00636 return wfTimestamp( TS_MW, $ts ); 00637 } 00638 00639 public function getComment() { 00640 return $this->comment; 00641 } 00642 00643 public function getDeleted() { 00644 return (int)$this->deleted; 00645 } 00646 }