MediaWiki  1.29.2
MovePage.php
Go to the documentation of this file.
1 <?php
2 
23 
30 class MovePage {
31 
35  protected $oldTitle;
36 
40  protected $newTitle;
41 
42  public function __construct( Title $oldTitle, Title $newTitle ) {
43  $this->oldTitle = $oldTitle;
44  $this->newTitle = $newTitle;
45  }
46 
47  public function checkPermissions( User $user, $reason ) {
48  $status = new Status();
49 
50  $errors = wfMergeErrorArrays(
51  $this->oldTitle->getUserPermissionsErrors( 'move', $user ),
52  $this->oldTitle->getUserPermissionsErrors( 'edit', $user ),
53  $this->newTitle->getUserPermissionsErrors( 'move-target', $user ),
54  $this->newTitle->getUserPermissionsErrors( 'edit', $user )
55  );
56 
57  // Convert into a Status object
58  if ( $errors ) {
59  foreach ( $errors as $error ) {
60  call_user_func_array( [ $status, 'fatal' ], $error );
61  }
62  }
63 
64  if ( EditPage::matchSummarySpamRegex( $reason ) !== false ) {
65  // This is kind of lame, won't display nice
66  $status->fatal( 'spamprotectiontext' );
67  }
68 
69  $tp = $this->newTitle->getTitleProtection();
70  if ( $tp !== false && !$user->isAllowed( $tp['permission'] ) ) {
71  $status->fatal( 'cantmove-titleprotected' );
72  }
73 
74  Hooks::run( 'MovePageCheckPermissions',
75  [ $this->oldTitle, $this->newTitle, $user, $reason, $status ]
76  );
77 
78  return $status;
79  }
80 
88  public function isValidMove() {
89  global $wgContentHandlerUseDB;
90  $status = new Status();
91 
92  if ( $this->oldTitle->equals( $this->newTitle ) ) {
93  $status->fatal( 'selfmove' );
94  }
95  if ( !$this->oldTitle->isMovable() ) {
96  $status->fatal( 'immobile-source-namespace', $this->oldTitle->getNsText() );
97  }
98  if ( $this->newTitle->isExternal() ) {
99  $status->fatal( 'immobile-target-namespace-iw' );
100  }
101  if ( !$this->newTitle->isMovable() ) {
102  $status->fatal( 'immobile-target-namespace', $this->newTitle->getNsText() );
103  }
104 
105  $oldid = $this->oldTitle->getArticleID();
106 
107  if ( strlen( $this->newTitle->getDBkey() ) < 1 ) {
108  $status->fatal( 'articleexists' );
109  }
110  if (
111  ( $this->oldTitle->getDBkey() == '' ) ||
112  ( !$oldid ) ||
113  ( $this->newTitle->getDBkey() == '' )
114  ) {
115  $status->fatal( 'badarticleerror' );
116  }
117 
118  # The move is allowed only if (1) the target doesn't exist, or
119  # (2) the target is a redirect to the source, and has no history
120  # (so we can undo bad moves right after they're done).
121  if ( $this->newTitle->getArticleID() && !$this->isValidMoveTarget() ) {
122  $status->fatal( 'articleexists' );
123  }
124 
125  // Content model checks
126  if ( !$wgContentHandlerUseDB &&
127  $this->oldTitle->getContentModel() !== $this->newTitle->getContentModel() ) {
128  // can't move a page if that would change the page's content model
129  $status->fatal(
130  'bad-target-model',
131  ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
132  ContentHandler::getLocalizedName( $this->newTitle->getContentModel() )
133  );
134  } elseif (
135  !ContentHandler::getForTitle( $this->oldTitle )->canBeUsedOn( $this->newTitle )
136  ) {
137  $status->fatal(
138  'content-not-allowed-here',
139  ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
140  $this->newTitle->getPrefixedText()
141  );
142  }
143 
144  // Image-specific checks
145  if ( $this->oldTitle->inNamespace( NS_FILE ) ) {
146  $status->merge( $this->isValidFileMove() );
147  }
148 
149  if ( $this->newTitle->inNamespace( NS_FILE ) && !$this->oldTitle->inNamespace( NS_FILE ) ) {
150  $status->fatal( 'nonfile-cannot-move-to-file' );
151  }
152 
153  // Hook for extensions to say a title can't be moved for technical reasons
154  Hooks::run( 'MovePageIsValidMove', [ $this->oldTitle, $this->newTitle, $status ] );
155 
156  return $status;
157  }
158 
164  protected function isValidFileMove() {
165  $status = new Status();
166  $file = wfLocalFile( $this->oldTitle );
167  $file->load( File::READ_LATEST );
168  if ( $file->exists() ) {
169  if ( $this->newTitle->getText() != wfStripIllegalFilenameChars( $this->newTitle->getText() ) ) {
170  $status->fatal( 'imageinvalidfilename' );
171  }
172  if ( !File::checkExtensionCompatibility( $file, $this->newTitle->getDBkey() ) ) {
173  $status->fatal( 'imagetypemismatch' );
174  }
175  }
176 
177  if ( !$this->newTitle->inNamespace( NS_FILE ) ) {
178  $status->fatal( 'imagenocrossnamespace' );
179  }
180 
181  return $status;
182  }
183 
191  protected function isValidMoveTarget() {
192  # Is it an existing file?
193  if ( $this->newTitle->inNamespace( NS_FILE ) ) {
194  $file = wfLocalFile( $this->newTitle );
195  $file->load( File::READ_LATEST );
196  if ( $file->exists() ) {
197  wfDebug( __METHOD__ . ": file exists\n" );
198  return false;
199  }
200  }
201  # Is it a redirect with no history?
202  if ( !$this->newTitle->isSingleRevRedirect() ) {
203  wfDebug( __METHOD__ . ": not a one-rev redirect\n" );
204  return false;
205  }
206  # Get the article text
207  $rev = Revision::newFromTitle( $this->newTitle, false, Revision::READ_LATEST );
208  if ( !is_object( $rev ) ) {
209  return false;
210  }
211  $content = $rev->getContent();
212  # Does the redirect point to the source?
213  # Or is it a broken self-redirect, usually caused by namespace collisions?
214  $redirTitle = $content ? $content->getRedirectTarget() : null;
215 
216  if ( $redirTitle ) {
217  if ( $redirTitle->getPrefixedDBkey() !== $this->oldTitle->getPrefixedDBkey() &&
218  $redirTitle->getPrefixedDBkey() !== $this->newTitle->getPrefixedDBkey() ) {
219  wfDebug( __METHOD__ . ": redirect points to other page\n" );
220  return false;
221  } else {
222  return true;
223  }
224  } else {
225  # Fail safe (not a redirect after all. strange.)
226  wfDebug( __METHOD__ . ": failsafe: database says " . $this->newTitle->getPrefixedDBkey() .
227  " is a redirect, but it doesn't contain a valid redirect.\n" );
228  return false;
229  }
230  }
231 
240  public function move( User $user, $reason, $createRedirect, array $changeTags = [] ) {
241  global $wgCategoryCollation;
242 
243  Hooks::run( 'TitleMove', [ $this->oldTitle, $this->newTitle, $user ] );
244 
245  // If it is a file, move it first.
246  // It is done before all other moving stuff is done because it's hard to revert.
247  $dbw = wfGetDB( DB_MASTER );
248  if ( $this->oldTitle->getNamespace() == NS_FILE ) {
249  $file = wfLocalFile( $this->oldTitle );
250  $file->load( File::READ_LATEST );
251  if ( $file->exists() ) {
252  $status = $file->move( $this->newTitle );
253  if ( !$status->isOK() ) {
254  return $status;
255  }
256  }
257  // Clear RepoGroup process cache
258  RepoGroup::singleton()->clearCache( $this->oldTitle );
259  RepoGroup::singleton()->clearCache( $this->newTitle ); # clear false negative cache
260  }
261 
262  $dbw->startAtomic( __METHOD__ );
263 
264  Hooks::run( 'TitleMoveStarting', [ $this->oldTitle, $this->newTitle, $user ] );
265 
266  $pageid = $this->oldTitle->getArticleID( Title::GAID_FOR_UPDATE );
267  $protected = $this->oldTitle->isProtected();
268 
269  // Do the actual move; if this fails, it will throw an MWException(!)
270  $nullRevision = $this->moveToInternal( $user, $this->newTitle, $reason, $createRedirect,
271  $changeTags );
272 
273  // Refresh the sortkey for this row. Be careful to avoid resetting
274  // cl_timestamp, which may disturb time-based lists on some sites.
275  // @todo This block should be killed, it's duplicating code
276  // from LinksUpdate::getCategoryInsertions() and friends.
277  $prefixes = $dbw->select(
278  'categorylinks',
279  [ 'cl_sortkey_prefix', 'cl_to' ],
280  [ 'cl_from' => $pageid ],
281  __METHOD__
282  );
283  if ( $this->newTitle->getNamespace() == NS_CATEGORY ) {
284  $type = 'subcat';
285  } elseif ( $this->newTitle->getNamespace() == NS_FILE ) {
286  $type = 'file';
287  } else {
288  $type = 'page';
289  }
290  foreach ( $prefixes as $prefixRow ) {
291  $prefix = $prefixRow->cl_sortkey_prefix;
292  $catTo = $prefixRow->cl_to;
293  $dbw->update( 'categorylinks',
294  [
295  'cl_sortkey' => Collation::singleton()->getSortKey(
296  $this->newTitle->getCategorySortkey( $prefix ) ),
297  'cl_collation' => $wgCategoryCollation,
298  'cl_type' => $type,
299  'cl_timestamp=cl_timestamp' ],
300  [
301  'cl_from' => $pageid,
302  'cl_to' => $catTo ],
303  __METHOD__
304  );
305  }
306 
307  $redirid = $this->oldTitle->getArticleID();
308 
309  if ( $protected ) {
310  # Protect the redirect title as the title used to be...
311  $res = $dbw->select(
312  'page_restrictions',
313  '*',
314  [ 'pr_page' => $pageid ],
315  __METHOD__,
316  'FOR UPDATE'
317  );
318  $rowsInsert = [];
319  foreach ( $res as $row ) {
320  $rowsInsert[] = [
321  'pr_page' => $redirid,
322  'pr_type' => $row->pr_type,
323  'pr_level' => $row->pr_level,
324  'pr_cascade' => $row->pr_cascade,
325  'pr_user' => $row->pr_user,
326  'pr_expiry' => $row->pr_expiry
327  ];
328  }
329  $dbw->insert( 'page_restrictions', $rowsInsert, __METHOD__, [ 'IGNORE' ] );
330 
331  // Build comment for log
332  $comment = wfMessage(
333  'prot_1movedto2',
334  $this->oldTitle->getPrefixedText(),
335  $this->newTitle->getPrefixedText()
336  )->inContentLanguage()->text();
337  if ( $reason ) {
338  $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
339  }
340 
341  // reread inserted pr_ids for log relation
342  $insertedPrIds = $dbw->select(
343  'page_restrictions',
344  'pr_id',
345  [ 'pr_page' => $redirid ],
346  __METHOD__
347  );
348  $logRelationsValues = [];
349  foreach ( $insertedPrIds as $prid ) {
350  $logRelationsValues[] = $prid->pr_id;
351  }
352 
353  // Update the protection log
354  $logEntry = new ManualLogEntry( 'protect', 'move_prot' );
355  $logEntry->setTarget( $this->newTitle );
356  $logEntry->setComment( $comment );
357  $logEntry->setPerformer( $user );
358  $logEntry->setParameters( [
359  '4::oldtitle' => $this->oldTitle->getPrefixedText(),
360  ] );
361  $logEntry->setRelations( [ 'pr_id' => $logRelationsValues ] );
362  $logEntry->setTags( $changeTags );
363  $logId = $logEntry->insert();
364  $logEntry->publish( $logId );
365  }
366 
367  // Update *_from_namespace fields as needed
368  if ( $this->oldTitle->getNamespace() != $this->newTitle->getNamespace() ) {
369  $dbw->update( 'pagelinks',
370  [ 'pl_from_namespace' => $this->newTitle->getNamespace() ],
371  [ 'pl_from' => $pageid ],
372  __METHOD__
373  );
374  $dbw->update( 'templatelinks',
375  [ 'tl_from_namespace' => $this->newTitle->getNamespace() ],
376  [ 'tl_from' => $pageid ],
377  __METHOD__
378  );
379  $dbw->update( 'imagelinks',
380  [ 'il_from_namespace' => $this->newTitle->getNamespace() ],
381  [ 'il_from' => $pageid ],
382  __METHOD__
383  );
384  }
385 
386  # Update watchlists
387  $oldtitle = $this->oldTitle->getDBkey();
388  $newtitle = $this->newTitle->getDBkey();
389  $oldsnamespace = MWNamespace::getSubject( $this->oldTitle->getNamespace() );
390  $newsnamespace = MWNamespace::getSubject( $this->newTitle->getNamespace() );
391  if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
392  $store = MediaWikiServices::getInstance()->getWatchedItemStore();
393  $store->duplicateAllAssociatedEntries( $this->oldTitle, $this->newTitle );
394  }
395 
396  Hooks::run(
397  'TitleMoveCompleting',
398  [ $this->oldTitle, $this->newTitle,
399  $user, $pageid, $redirid, $reason, $nullRevision ]
400  );
401 
402  $dbw->endAtomic( __METHOD__ );
403 
404  $params = [
407  &$user,
408  $pageid,
409  $redirid,
410  $reason,
411  $nullRevision
412  ];
413  // Keep each single hook handler atomic
416  $dbw,
417  __METHOD__,
418  function () use ( $params ) {
419  Hooks::run( 'TitleMoveComplete', $params );
420  }
421  )
422  );
423 
424  return Status::newGood();
425  }
426 
442  private function moveToInternal( User $user, &$nt, $reason = '', $createRedirect = true,
443  array $changeTags = [] ) {
444 
446  if ( $nt->exists() ) {
447  $moveOverRedirect = true;
448  $logType = 'move_redir';
449  } else {
450  $moveOverRedirect = false;
451  $logType = 'move';
452  }
453 
454  if ( $moveOverRedirect ) {
455  $overwriteMessage = wfMessage(
456  'delete_and_move_reason',
457  $this->oldTitle->getPrefixedText()
458  )->inContentLanguage()->text();
459  $newpage = WikiPage::factory( $nt );
460  $errs = [];
461  $status = $newpage->doDeleteArticleReal(
462  $overwriteMessage,
463  /* $suppress */ false,
464  $nt->getArticleID(),
465  /* $commit */ false,
466  $errs,
467  $user,
468  $changeTags,
469  'delete_redir'
470  );
471 
472  if ( !$status->isGood() ) {
473  throw new MWException( 'Failed to delete page-move revision: ' . $status );
474  }
475 
476  $nt->resetArticleID( false );
477  }
478 
479  if ( $createRedirect ) {
480  if ( $this->oldTitle->getNamespace() == NS_CATEGORY
481  && !wfMessage( 'category-move-redirect-override' )->inContentLanguage()->isDisabled()
482  ) {
483  $redirectContent = new WikitextContent(
484  wfMessage( 'category-move-redirect-override' )
485  ->params( $nt->getPrefixedText() )->inContentLanguage()->plain() );
486  } else {
487  $contentHandler = ContentHandler::getForTitle( $this->oldTitle );
488  $redirectContent = $contentHandler->makeRedirectContent( $nt,
489  wfMessage( 'move-redirect-text' )->inContentLanguage()->plain() );
490  }
491 
492  // NOTE: If this page's content model does not support redirects, $redirectContent will be null.
493  } else {
494  $redirectContent = null;
495  }
496 
497  // Figure out whether the content model is no longer the default
498  $oldDefault = ContentHandler::getDefaultModelFor( $this->oldTitle );
499  $contentModel = $this->oldTitle->getContentModel();
500  $newDefault = ContentHandler::getDefaultModelFor( $nt );
501  $defaultContentModelChanging = ( $oldDefault !== $newDefault
502  && $oldDefault === $contentModel );
503 
504  // T59084: log_page should be the ID of the *moved* page
505  $oldid = $this->oldTitle->getArticleID();
506  $logTitle = clone $this->oldTitle;
507 
508  $logEntry = new ManualLogEntry( 'move', $logType );
509  $logEntry->setPerformer( $user );
510  $logEntry->setTarget( $logTitle );
511  $logEntry->setComment( $reason );
512  $logEntry->setParameters( [
513  '4::target' => $nt->getPrefixedText(),
514  '5::noredir' => $redirectContent ? '0': '1',
515  ] );
516 
517  $formatter = LogFormatter::newFromEntry( $logEntry );
518  $formatter->setContext( RequestContext::newExtraneousContext( $this->oldTitle ) );
519  $comment = $formatter->getPlainActionText();
520  if ( $reason ) {
521  $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
522  }
523  # Truncate for whole multibyte characters.
524  $comment = $wgContLang->truncate( $comment, 255 );
525 
526  $dbw = wfGetDB( DB_MASTER );
527 
528  $oldpage = WikiPage::factory( $this->oldTitle );
529  $oldcountable = $oldpage->isCountable();
530 
531  $newpage = WikiPage::factory( $nt );
532 
533  # Save a null revision in the page's history notifying of the move
534  $nullRevision = Revision::newNullRevision( $dbw, $oldid, $comment, true, $user );
535  if ( !is_object( $nullRevision ) ) {
536  throw new MWException( 'No valid null revision produced in ' . __METHOD__ );
537  }
538 
539  $nullRevId = $nullRevision->insertOn( $dbw );
540  $logEntry->setAssociatedRevId( $nullRevId );
541 
542  # Change the name of the target page:
543  $dbw->update( 'page',
544  /* SET */ [
545  'page_namespace' => $nt->getNamespace(),
546  'page_title' => $nt->getDBkey(),
547  ],
548  /* WHERE */ [ 'page_id' => $oldid ],
549  __METHOD__
550  );
551 
552  if ( !$redirectContent ) {
553  // Clean up the old title *before* reset article id - T47348
554  WikiPage::onArticleDelete( $this->oldTitle );
555  }
556 
557  $this->oldTitle->resetArticleID( 0 ); // 0 == non existing
558  $nt->resetArticleID( $oldid );
559  $newpage->loadPageData( WikiPage::READ_LOCKING ); // T48397
560 
561  $newpage->updateRevisionOn( $dbw, $nullRevision );
562 
563  Hooks::run( 'NewRevisionFromEditComplete',
564  [ $newpage, $nullRevision, $nullRevision->getParentId(), $user ] );
565 
566  $newpage->doEditUpdates( $nullRevision, $user,
567  [ 'changed' => false, 'moved' => true, 'oldcountable' => $oldcountable ] );
568 
569  // If the default content model changes, we need to populate rev_content_model
570  if ( $defaultContentModelChanging ) {
571  $dbw->update(
572  'revision',
573  [ 'rev_content_model' => $contentModel ],
574  [ 'rev_page' => $nt->getArticleID(), 'rev_content_model IS NULL' ],
575  __METHOD__
576  );
577  }
578 
580 
581  # Recreate the redirect, this time in the other direction.
582  if ( $redirectContent ) {
583  $redirectArticle = WikiPage::factory( $this->oldTitle );
584  $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // T48397
585  $newid = $redirectArticle->insertOn( $dbw );
586  if ( $newid ) { // sanity
587  $this->oldTitle->resetArticleID( $newid );
588  $redirectRevision = new Revision( [
589  'title' => $this->oldTitle, // for determining the default content model
590  'page' => $newid,
591  'user_text' => $user->getName(),
592  'user' => $user->getId(),
593  'comment' => $comment,
594  'content' => $redirectContent ] );
595  $redirectRevId = $redirectRevision->insertOn( $dbw );
596  $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
597 
598  Hooks::run( 'NewRevisionFromEditComplete',
599  [ $redirectArticle, $redirectRevision, false, $user ] );
600 
601  $redirectArticle->doEditUpdates( $redirectRevision, $user, [ 'created' => true ] );
602 
603  ChangeTags::addTags( $changeTags, null, $redirectRevId, null );
604  }
605  }
606 
607  # Log the move
608  $logid = $logEntry->insert();
609 
610  $logEntry->setTags( $changeTags );
611  $logEntry->publish( $logid );
612 
613  return $nullRevision;
614  }
615 }
MovePage\checkPermissions
checkPermissions(User $user, $reason)
Definition: MovePage.php:47
File\checkExtensionCompatibility
static checkExtensionCompatibility(File $old, $new)
Checks if file extensions are compatible.
Definition: File.php:249
WikiPage\onArticleCreate
static onArticleCreate(Title $title)
The onArticle*() functions are supposed to be a kind of hooks which should be called whenever any of ...
Definition: WikiPage.php:3243
RepoGroup\singleton
static singleton()
Get a RepoGroup instance.
Definition: RepoGroup.php:59
wfMergeErrorArrays
wfMergeErrorArrays()
Merge arrays in the style of getUserPermissionsErrors, with duplicate removal e.g.
Definition: GlobalFunctions.php:242
MovePage\__construct
__construct(Title $oldTitle, Title $newTitle)
Definition: MovePage.php:42
MovePage\isValidMoveTarget
isValidMoveTarget()
Checks if $this can be moved to a given Title.
Definition: MovePage.php:191
MovePage\$oldTitle
Title $oldTitle
Definition: MovePage.php:35
$status
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
Definition: hooks.txt:1049
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:246
MovePage\move
move(User $user, $reason, $createRedirect, array $changeTags=[])
Definition: MovePage.php:240
DeferredUpdates\addUpdate
static addUpdate(DeferrableUpdate $update, $stage=self::POSTSEND)
Add an update to the deferred list to be run later by execute()
Definition: DeferredUpdates.php:76
MovePage\isValidMove
isValidMove()
Does various sanity checks that the move is valid.
Definition: MovePage.php:88
NS_FILE
const NS_FILE
Definition: Defines.php:68
$params
$params
Definition: styleTest.css.php:40
RequestContext\newExtraneousContext
static newExtraneousContext(Title $title, $request=[])
Create a new extraneous context.
Definition: RequestContext.php:638
ContentHandler\getForTitle
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
Definition: ContentHandler.php:240
$res
$res
Definition: database.txt:21
$type
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2536
Revision\insertOn
insertOn( $dbw)
Insert a new revision into the database, returning the new revision ID number on success and dies hor...
Definition: Revision.php:1398
cache
you have access to all of the normal MediaWiki so you can get a DB use the cache
Definition: maintenance.txt:52
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
IDBAccessObject\READ_LOCKING
const READ_LOCKING
Constants for object loading bitfield flags (higher => higher QoS)
Definition: IDBAccessObject.php:62
Status
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:40
Collation\singleton
static singleton()
Definition: Collation.php:34
Revision
Definition: Revision.php:33
Revision\newFromTitle
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given link target.
Definition: Revision.php:134
ContentHandler\getDefaultModelFor
static getDefaultModelFor(Title $title)
Returns the name of the default content model to be used for the page with the given title.
Definition: ContentHandler.php:178
MWException
MediaWiki exception.
Definition: MWException.php:26
wfStripIllegalFilenameChars
wfStripIllegalFilenameChars( $name)
Replace all invalid characters with '-'.
Definition: GlobalFunctions.php:3272
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:120
MovePage
Handles the backend logic of moving a page from one title to another.
Definition: MovePage.php:30
$content
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
Definition: hooks.txt:1049
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3060
WikiPage\onArticleDelete
static onArticleDelete(Title $title)
Clears caches when article is deleted.
Definition: WikiPage.php:3272
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:76
DB_MASTER
const DB_MASTER
Definition: defines.php:26
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:33
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:999
AtomicSectionUpdate
Deferrable Update for closure/callback updates via IDatabase::doAtomicSection()
Definition: AtomicSectionUpdate.php:9
ContentHandler\getLocalizedName
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
Definition: ContentHandler.php:348
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:76
EditPage\matchSummarySpamRegex
static matchSummarySpamRegex( $text)
Check given input text against $wgSummarySpamRegex, and return the text of the first match.
Definition: EditPage.php:2322
Title\GAID_FOR_UPDATE
const GAID_FOR_UPDATE
Used to be GAID_FOR_UPDATE define.
Definition: Title.php:54
MovePage\moveToInternal
moveToInternal(User $user, &$nt, $reason='', $createRedirect=true, array $changeTags=[])
Move page to a title which is either a redirect to the source page or nonexistent.
Definition: MovePage.php:442
MovePage\$newTitle
Title $newTitle
Definition: MovePage.php:40
plain
either a plain
Definition: hooks.txt:2007
Title
Represents a title within MediaWiki.
Definition: Title.php:39
$rev
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1741
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
MovePage\isValidFileMove
isValidFileMove()
Sanity checks for when a file is being moved.
Definition: MovePage.php:164
ManualLogEntry
Class for creating log entries manually, to inject them into the database.
Definition: LogEntry.php:396
Revision\newNullRevision
static newNullRevision( $dbw, $pageId, $summary, $minor, $user=null)
Create a new null-revision for insertion into a page's history.
Definition: Revision.php:1693
wfMessage
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
MediaWikiServices
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
MWNamespace\getSubject
static getSubject( $index)
Get the subject namespace index for a given namespace Special namespaces (NS_MEDIA,...
Definition: MWNamespace.php:121
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:50
wfLocalFile
wfLocalFile( $title)
Get an object referring to a locally registered file.
Definition: GlobalFunctions.php:3112
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
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:136
array
the array() calling protocol came about after MediaWiki 1.4rc1.
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
LogFormatter\newFromEntry
static newFromEntry(LogEntry $entry)
Constructs a new formatter suitable for given entry.
Definition: LogFormatter.php:48