MediaWiki  master
ManualLogEntry.php
Go to the documentation of this file.
1 <?php
31 use Wikimedia\Assert\Assert;
32 use Wikimedia\IPUtils;
34 
45 class ManualLogEntry extends LogEntryBase implements Taggable {
47  protected $type;
48 
50  protected $subtype;
51 
53  protected $parameters = [];
54 
56  protected $relations = [];
57 
59  protected $performer;
60 
62  protected $target;
63 
65  protected $timestamp;
66 
68  protected $comment = '';
69 
71  protected $revId = 0;
72 
74  protected $tags = [];
75 
77  protected $deleted;
78 
80  protected $id;
81 
83  protected $isPatrollable = false;
84 
86  protected $legacy = false;
87 
96  public function __construct( $type, $subtype ) {
97  $this->type = $type;
98  $this->subtype = $subtype;
99  }
100 
131  public function setParameters( $parameters ) {
132  $this->parameters = $parameters;
133  }
134 
142  public function setRelations( array $relations ) {
143  $this->relations = $relations;
144  }
145 
152  public function setPerformer( UserIdentity $performer ) {
153  $this->performer = $performer;
154  }
155 
163  public function setTarget( $target ) {
164  if ( $target instanceof PageReference ) {
165  $this->target = Title::castFromPageReference( $target );
166  } elseif ( $target instanceof LinkTarget ) {
167  $this->target = Title::newFromLinkTarget( $target );
168  } else {
169  throw new InvalidArgumentException( "Invalid target provided" );
170  }
171  }
172 
179  public function setTimestamp( $timestamp ) {
180  $this->timestamp = $timestamp;
181  }
182 
189  public function setComment( $comment ) {
190  $this->comment = $comment;
191  }
192 
202  public function setAssociatedRevId( $revId ) {
203  $this->revId = $revId;
204  }
205 
216  public function setTags( $tags ) {
217  if ( $this->tags ) {
218  wfDebug( 'Overwriting existing ManualLogEntry tags' );
219  }
220  $this->tags = [];
221  $this->addTags( $tags );
222  }
223 
230  public function addTags( $tags ) {
231  if ( $tags === null ) {
232  return;
233  }
234 
235  if ( is_string( $tags ) ) {
236  $tags = [ $tags ];
237  }
238  Assert::parameterElementType( 'string', $tags, 'tags' );
239  $this->tags = array_unique( array_merge( $this->tags, $tags ) );
240  }
241 
251  public function setIsPatrollable( $patrollable ) {
252  $this->isPatrollable = (bool)$patrollable;
253  }
254 
261  public function setLegacy( $legacy ) {
262  $this->legacy = $legacy;
263  }
264 
271  public function setDeleted( $deleted ) {
272  $this->deleted = $deleted;
273  }
274 
282  public function insert( IDatabase $dbw = null ) {
283  $dbw = $dbw ?: wfGetDB( DB_PRIMARY );
284 
285  if ( $this->timestamp === null ) {
286  $this->timestamp = wfTimestampNow();
287  }
288 
289  $actorId = MediaWikiServices::getInstance()->getActorStore()
290  ->acquireActorId( $this->getPerformerIdentity(), $dbw );
291 
292  // Trim spaces on user supplied text
293  $comment = trim( $this->getComment() );
294 
295  $params = $this->getParameters();
297 
298  // Additional fields for which there's no space in the database table schema
299  $revId = $this->getAssociatedRevId();
300  if ( $revId ) {
301  $params['associated_rev_id'] = $revId;
302  $relations['associated_rev_id'] = $revId;
303  }
304 
305  $data = [
306  'log_type' => $this->getType(),
307  'log_action' => $this->getSubtype(),
308  'log_timestamp' => $dbw->timestamp( $this->getTimestamp() ),
309  'log_actor' => $actorId,
310  'log_namespace' => $this->getTarget()->getNamespace(),
311  'log_title' => $this->getTarget()->getDBkey(),
312  'log_page' => $this->getTarget()->getArticleID(),
313  'log_params' => LogEntryBase::makeParamBlob( $params ),
314  ];
315  if ( isset( $this->deleted ) ) {
316  $data['log_deleted'] = $this->deleted;
317  }
318  $data += CommentStore::getStore()->insert( $dbw, 'log_comment', $comment );
319 
320  $dbw->insert( 'logging', $data, __METHOD__ );
321  $this->id = $dbw->insertId();
322 
323  $rows = [];
324  foreach ( $relations as $tag => $values ) {
325  if ( !strlen( $tag ) ) {
326  throw new MWException( "Got empty log search tag." );
327  }
328 
329  if ( !is_array( $values ) ) {
330  $values = [ $values ];
331  }
332 
333  foreach ( $values as $value ) {
334  $rows[] = [
335  'ls_field' => $tag,
336  'ls_value' => $value,
337  'ls_log_id' => $this->id
338  ];
339  }
340  }
341  if ( count( $rows ) ) {
342  $dbw->insert( 'log_search', $rows, __METHOD__, [ 'IGNORE' ] );
343  }
344 
345  return $this->id;
346  }
347 
355  public function getRecentChange( $newId = 0 ) {
356  $formatter = LogFormatter::newFromEntry( $this );
357  $context = RequestContext::newExtraneousContext( $this->getTarget() );
358  $formatter->setContext( $context );
359 
360  $logpage = SpecialPage::getTitleFor( 'Log', $this->getType() );
361  $user = $this->getPerformerIdentity();
362  $ip = "";
363  if ( !$user->isRegistered() ) {
364  // "MediaWiki default" and friends may have
365  // no IP address in their name
366  if ( IPUtils::isIPAddress( $user->getName() ) ) {
367  $ip = $user->getName();
368  }
369  }
370 
372  $this->getTimestamp(),
373  $logpage,
374  $user,
375  $formatter->getPlainActionText(),
376  $ip,
377  $this->getType(),
378  $this->getSubtype(),
379  $this->getTarget(),
380  $this->getComment(),
381  LogEntryBase::makeParamBlob( $this->getParameters() ),
382  $newId,
383  $formatter->getIRCActionComment(), // Used for IRC feeds
384  $this->getAssociatedRevId(), // Used for e.g. moves and uploads
385  $this->getIsPatrollable()
386  );
387  }
388 
395  public function publish( $newId, $to = 'rcandudp' ) {
396  $canAddTags = true;
397  // FIXME: this code should be removed once all callers properly call publish()
398  if ( $to === 'udp' && !$newId && !$this->getAssociatedRevId() ) {
399  \MediaWiki\Logger\LoggerFactory::getInstance( 'logging' )->warning(
400  'newId and/or revId must be set when calling ManualLogEntry::publish()',
401  [
402  'newId' => $newId,
403  'to' => $to,
404  'revId' => $this->getAssociatedRevId(),
405  // pass a new exception to register the stack trace
406  'exception' => new RuntimeException()
407  ]
408  );
409  $canAddTags = false;
410  }
411 
413  function () use ( $newId, $to, $canAddTags ) {
414  $log = new LogPage( $this->getType() );
415  if ( !$log->isRestricted() ) {
416  Hooks::runner()->onManualLogEntryBeforePublish( $this );
417  $rc = $this->getRecentChange( $newId );
418 
419  if ( $to === 'rc' || $to === 'rcandudp' ) {
420  // save RC, passing tags so they are applied there
421  $rc->addTags( $this->getTags() );
422  $rc->save( $rc::SEND_NONE );
423  } else {
424  $tags = $this->getTags();
425  if ( $tags && $canAddTags ) {
426  $revId = $this->getAssociatedRevId();
428  $tags,
429  null,
430  $revId > 0 ? $revId : null,
431  $newId > 0 ? $newId : null
432  );
433  }
434  }
435 
436  if ( $to === 'udp' || $to === 'rcandudp' ) {
437  $rc->notifyRCFeeds();
438  }
439  }
440  },
441  DeferredUpdates::POSTSEND,
443  );
444  }
445 
449  public function getType() {
450  return $this->type;
451  }
452 
456  public function getSubtype() {
457  return $this->subtype;
458  }
459 
463  public function getParameters() {
464  return $this->parameters;
465  }
466 
470  public function getPerformerIdentity(): UserIdentity {
471  return $this->performer;
472  }
473 
477  public function getTarget() {
478  return $this->target;
479  }
480 
484  public function getTimestamp() {
485  $ts = $this->timestamp ?? wfTimestampNow();
486 
487  return wfTimestamp( TS_MW, $ts );
488  }
489 
493  public function getComment() {
494  return $this->comment;
495  }
496 
501  public function getAssociatedRevId() {
502  return $this->revId;
503  }
504 
509  public function getTags() {
510  return $this->tags;
511  }
512 
519  public function getIsPatrollable() {
520  return $this->isPatrollable;
521  }
522 
527  public function isLegacy() {
528  return $this->legacy;
529  }
530 
534  public function getDeleted() {
535  return (int)$this->deleted;
536  }
537 }
ManualLogEntry\setTimestamp
setTimestamp( $timestamp)
Set the timestamp of when the logged action took place.
Definition: ManualLogEntry.php:179
ManualLogEntry\__construct
__construct( $type, $subtype)
Definition: ManualLogEntry.php:96
ManualLogEntry\getTarget
getTarget()
Definition: ManualLogEntry.php:477
RecentChange\newLogEntry
static newLogEntry( $timestamp, $logPage, $user, $actionComment, $ip, $type, $action, $target, $logComment, $params, $newId=0, $actionCommentIRC='', $revId=0, $isPatrollable=false)
Definition: RecentChange.php:925
ManualLogEntry\$deleted
int $deleted
Deletion state of the log entry.
Definition: ManualLogEntry.php:77
ManualLogEntry\getType
getType()
Definition: ManualLogEntry.php:449
ManualLogEntry\insert
insert(IDatabase $dbw=null)
Insert the entry into the logging table.
Definition: ManualLogEntry.php:282
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:203
ManualLogEntry\$performer
UserIdentity $performer
Performer of the action for the log entry.
Definition: ManualLogEntry.php:59
MediaWiki\Logger\LoggerFactory\getInstance
static getInstance( $channel)
Get a named logger instance from the currently configured logger factory.
Definition: LoggerFactory.php:92
ManualLogEntry\setAssociatedRevId
setAssociatedRevId( $revId)
Set an associated revision id.
Definition: ManualLogEntry.php:202
ManualLogEntry\getParameters
getParameters()
Definition: ManualLogEntry.php:463
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1649
ManualLogEntry\getComment
getComment()
Definition: ManualLogEntry.php:493
RequestContext\newExtraneousContext
static newExtraneousContext(Title $title, $request=[])
Create a new extraneous context.
Definition: RequestContext.php:658
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:131
MediaWiki\ChangeTags\Taggable
Interface that defines how to tag objects.
Definition: Taggable.php:32
ManualLogEntry\setRelations
setRelations(array $relations)
Declare arbitrary tag/value relations to this log entry.
Definition: ManualLogEntry.php:142
ManualLogEntry\addTags
addTags( $tags)
Add change tags for the log entry.
Definition: ManualLogEntry.php:230
Page\PageReference
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
Definition: PageReference.php:49
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
ManualLogEntry\getTimestamp
getTimestamp()
Definition: ManualLogEntry.php:484
ManualLogEntry\$legacy
bool $legacy
Whether this is a legacy log entry.
Definition: ManualLogEntry.php:86
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
ManualLogEntry\setTags
setTags( $tags)
Set change tags for the log entry.
Definition: ManualLogEntry.php:216
ManualLogEntry\$comment
string $comment
Comment for the log entry.
Definition: ManualLogEntry.php:68
ManualLogEntry\$parameters
array $parameters
Parameters for log entry.
Definition: ManualLogEntry.php:53
ManualLogEntry\getRecentChange
getRecentChange( $newId=0)
Get a RecentChanges object for the log entry.
Definition: ManualLogEntry.php:355
ManualLogEntry\isLegacy
isLegacy()
Definition: ManualLogEntry.php:527
MWException
MediaWiki exception.
Definition: MWException.php:29
ManualLogEntry\setComment
setComment( $comment)
Set a comment associated with the action being logged.
Definition: ManualLogEntry.php:189
ManualLogEntry\$tags
string[] $tags
Change tags add to the log entry.
Definition: ManualLogEntry.php:74
ManualLogEntry\$id
int $id
ID of the log entry.
Definition: ManualLogEntry.php:80
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2186
ManualLogEntry\getPerformerIdentity
getPerformerIdentity()
Definition: ManualLogEntry.php:470
LogPage
Class to simplify the use of log pages.
Definition: LogPage.php:38
ManualLogEntry\getSubtype
getSubtype()
Definition: ManualLogEntry.php:456
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1678
ManualLogEntry\$subtype
string $subtype
Sub type of log entry.
Definition: ManualLogEntry.php:50
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:894
ManualLogEntry\setParameters
setParameters( $parameters)
Set extra log parameters.
Definition: ManualLogEntry.php:131
ManualLogEntry\publish
publish( $newId, $to='rcandudp')
Publish the log entry.
Definition: ManualLogEntry.php:395
ManualLogEntry\$relations
array $relations
Definition: ManualLogEntry.php:56
LogEntryBase
Extends the LogEntry Interface with some basic functionality.
Definition: LogEntryBase.php:31
ManualLogEntry\setIsPatrollable
setIsPatrollable( $patrollable)
Set whether this log entry should be made patrollable This shouldn't depend on config,...
Definition: ManualLogEntry.php:251
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
ManualLogEntry\setDeleted
setDeleted( $deleted)
Set the 'deleted' flag.
Definition: ManualLogEntry.php:271
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
ManualLogEntry\$timestamp
string $timestamp
Timestamp of creation of the log entry.
Definition: ManualLogEntry.php:65
Title\newFromLinkTarget
static newFromLinkTarget(LinkTarget $linkTarget, $forceClone='')
Returns a Title given a LinkTarget.
Definition: Title.php:289
ManualLogEntry\getTags
getTags()
Definition: ManualLogEntry.php:509
Title
Represents a title within MediaWiki.
Definition: Title.php:47
ManualLogEntry\getDeleted
getDeleted()
Definition: ManualLogEntry.php:534
LogEntryBase\makeParamBlob
static makeParamBlob( $params)
Create a blob from a parameter array.
Definition: LogEntryBase.php:58
ManualLogEntry\$revId
int $revId
A rev id associated to the log entry.
Definition: ManualLogEntry.php:71
ManualLogEntry\getIsPatrollable
getIsPatrollable()
Whether this log entry is patrollable.
Definition: ManualLogEntry.php:519
ManualLogEntry\$target
Title $target
Target title for the log entry.
Definition: ManualLogEntry.php:62
ManualLogEntry
Class for creating new log entries and inserting them into the database.
Definition: ManualLogEntry.php:45
Title\castFromPageReference
static castFromPageReference(?PageReference $pageReference)
Return a Title for a given Reference.
Definition: Title.php:339
ManualLogEntry\setLegacy
setLegacy( $legacy)
Set the 'legacy' flag.
Definition: ManualLogEntry.php:261
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
ManualLogEntry\getAssociatedRevId
getAssociatedRevId()
Definition: ManualLogEntry.php:501
CommentStore\getStore
static getStore()
Definition: CommentStore.php:120
ManualLogEntry\setPerformer
setPerformer(UserIdentity $performer)
Set the user that performed the action being logged.
Definition: ManualLogEntry.php:152
DeferredUpdates\addCallableUpdate
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add an update to the pending update queue that invokes the specified callback when run.
Definition: DeferredUpdates.php:151
ManualLogEntry\setTarget
setTarget( $target)
Set the title of the object changed.
Definition: ManualLogEntry.php:163
ManualLogEntry\$type
string $type
Type of log entry.
Definition: ManualLogEntry.php:47
ManualLogEntry\$isPatrollable
bool $isPatrollable
Can this log entry be patrolled?
Definition: ManualLogEntry.php:83
ChangeTags\addTags
static addTags( $tags, $rc_id=null, $rev_id=null, $log_id=null, $params=null, RecentChange $rc=null)
Add tags to a change given its rc_id, rev_id and/or log_id.
Definition: ChangeTags.php:333
LogFormatter\newFromEntry
static newFromEntry(LogEntry $entry)
Constructs a new formatter suitable for given entry.
Definition: LogFormatter.php:55