MediaWiki  1.27.1
LinkHolderArray.php
Go to the documentation of this file.
1 <?php
28  public $internals = [];
29  public $interwikis = [];
30  public $size = 0;
31 
35  public $parent;
36  protected $tempIdOffset;
37 
41  public function __construct( $parent ) {
42  $this->parent = $parent;
43  }
44 
48  public function __destruct() {
49  foreach ( $this as $name => $value ) {
50  unset( $this->$name );
51  }
52  }
53 
62  public function __sleep() {
63  foreach ( $this->internals as &$nsLinks ) {
64  foreach ( $nsLinks as &$entry ) {
65  unset( $entry['title'] );
66  }
67  }
68  unset( $nsLinks );
69  unset( $entry );
70 
71  foreach ( $this->interwikis as &$entry ) {
72  unset( $entry['title'] );
73  }
74  unset( $entry );
75 
76  return [ 'internals', 'interwikis', 'size' ];
77  }
78 
82  public function __wakeup() {
83  foreach ( $this->internals as &$nsLinks ) {
84  foreach ( $nsLinks as &$entry ) {
85  $entry['title'] = Title::newFromText( $entry['pdbk'] );
86  }
87  }
88  unset( $nsLinks );
89  unset( $entry );
90 
91  foreach ( $this->interwikis as &$entry ) {
92  $entry['title'] = Title::newFromText( $entry['pdbk'] );
93  }
94  unset( $entry );
95  }
96 
101  public function merge( $other ) {
102  foreach ( $other->internals as $ns => $entries ) {
103  $this->size += count( $entries );
104  if ( !isset( $this->internals[$ns] ) ) {
105  $this->internals[$ns] = $entries;
106  } else {
107  $this->internals[$ns] += $entries;
108  }
109  }
110  $this->interwikis += $other->interwikis;
111  }
112 
125  public function mergeForeign( $other, $texts ) {
126  $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
127  $maxId = 0;
128 
129  # Renumber internal links
130  foreach ( $other->internals as $ns => $nsLinks ) {
131  foreach ( $nsLinks as $key => $entry ) {
132  $newKey = $idOffset + $key;
133  $this->internals[$ns][$newKey] = $entry;
134  $maxId = $newKey > $maxId ? $newKey : $maxId;
135  }
136  }
137  $texts = preg_replace_callback( '/(<!--LINK \d+:)(\d+)(-->)/',
138  [ $this, 'mergeForeignCallback' ], $texts );
139 
140  # Renumber interwiki links
141  foreach ( $other->interwikis as $key => $entry ) {
142  $newKey = $idOffset + $key;
143  $this->interwikis[$newKey] = $entry;
144  $maxId = $newKey > $maxId ? $newKey : $maxId;
145  }
146  $texts = preg_replace_callback( '/(<!--IWLINK )(\d+)(-->)/',
147  [ $this, 'mergeForeignCallback' ], $texts );
148 
149  # Set the parent link ID to be beyond the highest used ID
150  $this->parent->setLinkID( $maxId + 1 );
151  $this->tempIdOffset = null;
152  return $texts;
153  }
154 
159  protected function mergeForeignCallback( $m ) {
160  return $m[1] . ( $m[2] + $this->tempIdOffset ) . $m[3];
161  }
162 
169  public function getSubArray( $text ) {
170  $sub = new LinkHolderArray( $this->parent );
171 
172  # Internal links
173  $pos = 0;
174  while ( $pos < strlen( $text ) ) {
175  if ( !preg_match( '/<!--LINK (\d+):(\d+)-->/',
176  $text, $m, PREG_OFFSET_CAPTURE, $pos )
177  ) {
178  break;
179  }
180  $ns = $m[1][0];
181  $key = $m[2][0];
182  $sub->internals[$ns][$key] = $this->internals[$ns][$key];
183  $pos = $m[0][1] + strlen( $m[0][0] );
184  }
185 
186  # Interwiki links
187  $pos = 0;
188  while ( $pos < strlen( $text ) ) {
189  if ( !preg_match( '/<!--IWLINK (\d+)-->/', $text, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
190  break;
191  }
192  $key = $m[1][0];
193  $sub->interwikis[$key] = $this->interwikis[$key];
194  $pos = $m[0][1] + strlen( $m[0][0] );
195  }
196  return $sub;
197  }
198 
203  public function isBig() {
204  global $wgLinkHolderBatchSize;
205  return $this->size > $wgLinkHolderBatchSize;
206  }
207 
212  public function clear() {
213  $this->internals = [];
214  $this->interwikis = [];
215  $this->size = 0;
216  }
217 
231  public function makeHolder( $nt, $text = '', $query = [], $trail = '', $prefix = '' ) {
232  if ( !is_object( $nt ) ) {
233  # Fail gracefully
234  $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
235  } else {
236  # Separate the link trail from the rest of the link
237  list( $inside, $trail ) = Linker::splitTrail( $trail );
238 
239  $entry = [
240  'title' => $nt,
241  'text' => $prefix . $text . $inside,
242  'pdbk' => $nt->getPrefixedDBkey(),
243  ];
244  if ( $query !== [] ) {
245  $entry['query'] = $query;
246  }
247 
248  if ( $nt->isExternal() ) {
249  // Use a globally unique ID to keep the objects mergable
250  $key = $this->parent->nextLinkID();
251  $this->interwikis[$key] = $entry;
252  $retVal = "<!--IWLINK $key-->{$trail}";
253  } else {
254  $key = $this->parent->nextLinkID();
255  $ns = $nt->getNamespace();
256  $this->internals[$ns][$key] = $entry;
257  $retVal = "<!--LINK $ns:$key-->{$trail}";
258  }
259  $this->size++;
260  }
261  return $retVal;
262  }
263 
269  public function replace( &$text ) {
270 
271  $this->replaceInternal( $text );
272  $this->replaceInterwiki( $text );
273 
274  }
275 
280  protected function replaceInternal( &$text ) {
281  if ( !$this->internals ) {
282  return;
283  }
284 
285  global $wgContLang, $wgContentHandlerUseDB, $wgPageLanguageUseDB;
286 
287  $colours = [];
288  $linkCache = LinkCache::singleton();
289  $output = $this->parent->getOutput();
290 
291  $dbr = wfGetDB( DB_SLAVE );
292  $threshold = $this->parent->getOptions()->getStubThreshold();
293 
294  # Sort by namespace
295  ksort( $this->internals );
296 
297  $linkcolour_ids = [];
298 
299  # Generate query
300  $queries = [];
301  foreach ( $this->internals as $ns => $entries ) {
302  foreach ( $entries as $entry ) {
304  $title = $entry['title'];
305  $pdbk = $entry['pdbk'];
306 
307  # Skip invalid entries.
308  # Result will be ugly, but prevents crash.
309  if ( is_null( $title ) ) {
310  continue;
311  }
312 
313  # Check if it's a static known link, e.g. interwiki
314  if ( $title->isAlwaysKnown() ) {
315  $colours[$pdbk] = '';
316  } elseif ( $ns == NS_SPECIAL ) {
317  $colours[$pdbk] = 'new';
318  } else {
319  $id = $linkCache->getGoodLinkID( $pdbk );
320  if ( $id != 0 ) {
321  $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
322  $output->addLink( $title, $id );
323  $linkcolour_ids[$id] = $pdbk;
324  } elseif ( $linkCache->isBadLink( $pdbk ) ) {
325  $colours[$pdbk] = 'new';
326  } else {
327  # Not in the link cache, add it to the query
328  $queries[$ns][] = $title->getDBkey();
329  }
330  }
331  }
332  }
333  if ( $queries ) {
334  $where = [];
335  foreach ( $queries as $ns => $pages ) {
336  $where[] = $dbr->makeList(
337  [
338  'page_namespace' => $ns,
339  'page_title' => array_unique( $pages ),
340  ],
341  LIST_AND
342  );
343  }
344 
345  $fields = [ 'page_id', 'page_namespace', 'page_title',
346  'page_is_redirect', 'page_len', 'page_latest' ];
347 
348  if ( $wgContentHandlerUseDB ) {
349  $fields[] = 'page_content_model';
350  }
351  if ( $wgPageLanguageUseDB ) {
352  $fields[] = 'page_lang';
353  }
354 
355  $res = $dbr->select(
356  'page',
357  $fields,
358  $dbr->makeList( $where, LIST_OR ),
359  __METHOD__
360  );
361 
362  # Fetch data and form into an associative array
363  # non-existent = broken
364  foreach ( $res as $s ) {
365  $title = Title::makeTitle( $s->page_namespace, $s->page_title );
366  $pdbk = $title->getPrefixedDBkey();
367  $linkCache->addGoodLinkObjFromRow( $title, $s );
368  $output->addLink( $title, $s->page_id );
369  # @todo FIXME: Convoluted data flow
370  # The redirect status and length is passed to getLinkColour via the LinkCache
371  # Use formal parameters instead
372  $colours[$pdbk] = Linker::getLinkColour( $title, $threshold );
373  // add id to the extension todolist
374  $linkcolour_ids[$s->page_id] = $pdbk;
375  }
376  unset( $res );
377  }
378  if ( count( $linkcolour_ids ) ) {
379  // pass an array of page_ids to an extension
380  Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
381  }
382 
383  # Do a second query for different language variants of links and categories
384  if ( $wgContLang->hasVariants() ) {
385  $this->doVariants( $colours );
386  }
387 
388  # Construct search and replace arrays
389  $replacePairs = [];
390  foreach ( $this->internals as $ns => $entries ) {
391  foreach ( $entries as $index => $entry ) {
392  $pdbk = $entry['pdbk'];
393  $title = $entry['title'];
394  $query = isset( $entry['query'] ) ? $entry['query'] : [];
395  $key = "$ns:$index";
396  $searchkey = "<!--LINK $key-->";
397  $displayText = $entry['text'];
398  if ( isset( $entry['selflink'] ) ) {
399  $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
400  continue;
401  }
402  if ( $displayText === '' ) {
403  $displayText = null;
404  }
405  if ( !isset( $colours[$pdbk] ) ) {
406  $colours[$pdbk] = 'new';
407  }
408  $attribs = [];
409  if ( $colours[$pdbk] == 'new' ) {
410  $linkCache->addBadLinkObj( $title );
411  $output->addLink( $title, 0 );
412  $type = [ 'broken' ];
413  } else {
414  if ( $colours[$pdbk] != '' ) {
415  $attribs['class'] = $colours[$pdbk];
416  }
417  $type = [ 'known', 'noclasses' ];
418  }
419  $replacePairs[$searchkey] = Linker::link( $title, $displayText,
420  $attribs, $query, $type );
421  }
422  }
423  $replacer = new HashtableReplacer( $replacePairs, 1 );
424 
425  # Do the thing
426  $text = preg_replace_callback(
427  '/(<!--LINK .*?-->)/',
428  $replacer->cb(),
429  $text
430  );
431 
432  }
433 
438  protected function replaceInterwiki( &$text ) {
439  if ( empty( $this->interwikis ) ) {
440  return;
441  }
442 
443  # Make interwiki link HTML
444  $output = $this->parent->getOutput();
445  $replacePairs = [];
446  $options = [
447  'stubThreshold' => $this->parent->getOptions()->getStubThreshold(),
448  ];
449  foreach ( $this->interwikis as $key => $link ) {
450  $replacePairs[$key] = Linker::link( $link['title'], $link['text'], [], [], $options );
451  $output->addInterwikiLink( $link['title'] );
452  }
453  $replacer = new HashtableReplacer( $replacePairs, 1 );
454 
455  $text = preg_replace_callback(
456  '/<!--IWLINK (.*?)-->/',
457  $replacer->cb(),
458  $text );
459  }
460 
465  protected function doVariants( &$colours ) {
466  global $wgContLang, $wgContentHandlerUseDB, $wgPageLanguageUseDB;
467  $linkBatch = new LinkBatch();
468  $variantMap = []; // maps $pdbkey_Variant => $keys (of link holders)
469  $output = $this->parent->getOutput();
470  $linkCache = LinkCache::singleton();
471  $threshold = $this->parent->getOptions()->getStubThreshold();
472  $titlesToBeConverted = '';
473  $titlesAttrs = [];
474 
475  // Concatenate titles to a single string, thus we only need auto convert the
476  // single string to all variants. This would improve parser's performance
477  // significantly.
478  foreach ( $this->internals as $ns => $entries ) {
479  if ( $ns == NS_SPECIAL ) {
480  continue;
481  }
482  foreach ( $entries as $index => $entry ) {
483  $pdbk = $entry['pdbk'];
484  // we only deal with new links (in its first query)
485  if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
486  $titlesAttrs[] = [ $index, $entry['title'] ];
487  // separate titles with \0 because it would never appears
488  // in a valid title
489  $titlesToBeConverted .= $entry['title']->getText() . "\0";
490  }
491  }
492  }
493 
494  // Now do the conversion and explode string to text of titles
495  $titlesAllVariants = $wgContLang->autoConvertToAllVariants( rtrim( $titlesToBeConverted, "\0" ) );
496  $allVariantsName = array_keys( $titlesAllVariants );
497  foreach ( $titlesAllVariants as &$titlesVariant ) {
498  $titlesVariant = explode( "\0", $titlesVariant );
499  }
500 
501  // Then add variants of links to link batch
502  $parentTitle = $this->parent->getTitle();
503  foreach ( $titlesAttrs as $i => $attrs ) {
505  list( $index, $title ) = $attrs;
506  $ns = $title->getNamespace();
507  $text = $title->getText();
508 
509  foreach ( $allVariantsName as $variantName ) {
510  $textVariant = $titlesAllVariants[$variantName][$i];
511  if ( $textVariant === $text ) {
512  continue;
513  }
514 
515  $variantTitle = Title::makeTitle( $ns, $textVariant );
516  if ( is_null( $variantTitle ) ) {
517  continue;
518  }
519 
520  // Self-link checking for mixed/different variant titles. At this point, we
521  // already know the exact title does not exist, so the link cannot be to a
522  // variant of the current title that exists as a separate page.
523  if ( $variantTitle->equals( $parentTitle ) && !$title->hasFragment() ) {
524  $this->internals[$ns][$index]['selflink'] = true;
525  continue 2;
526  }
527 
528  $linkBatch->addObj( $variantTitle );
529  $variantMap[$variantTitle->getPrefixedDBkey()][] = "$ns:$index";
530  }
531  }
532 
533  // process categories, check if a category exists in some variant
534  $categoryMap = []; // maps $category_variant => $category (dbkeys)
535  $varCategories = []; // category replacements oldDBkey => newDBkey
536  foreach ( $output->getCategoryLinks() as $category ) {
537  $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category );
538  $linkBatch->addObj( $categoryTitle );
539  $variants = $wgContLang->autoConvertToAllVariants( $category );
540  foreach ( $variants as $variant ) {
541  if ( $variant !== $category ) {
542  $variantTitle = Title::makeTitleSafe( NS_CATEGORY, $variant );
543  if ( is_null( $variantTitle ) ) {
544  continue;
545  }
546  $linkBatch->addObj( $variantTitle );
547  $categoryMap[$variant] = [ $category, $categoryTitle ];
548  }
549  }
550  }
551 
552  if ( !$linkBatch->isEmpty() ) {
553  // construct query
554  $dbr = wfGetDB( DB_SLAVE );
555  $fields = [ 'page_id', 'page_namespace', 'page_title',
556  'page_is_redirect', 'page_len', 'page_latest' ];
557 
558  if ( $wgContentHandlerUseDB ) {
559  $fields[] = 'page_content_model';
560  }
561  if ( $wgPageLanguageUseDB ) {
562  $fields[] = 'page_lang';
563  }
564 
565  $varRes = $dbr->select( 'page',
566  $fields,
567  $linkBatch->constructSet( 'page', $dbr ),
568  __METHOD__
569  );
570 
571  $linkcolour_ids = [];
572 
573  // for each found variants, figure out link holders and replace
574  foreach ( $varRes as $s ) {
575  $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
576  $varPdbk = $variantTitle->getPrefixedDBkey();
577  $vardbk = $variantTitle->getDBkey();
578 
579  $holderKeys = [];
580  if ( isset( $variantMap[$varPdbk] ) ) {
581  $holderKeys = $variantMap[$varPdbk];
582  $linkCache->addGoodLinkObjFromRow( $variantTitle, $s );
583  $output->addLink( $variantTitle, $s->page_id );
584  }
585 
586  // loop over link holders
587  foreach ( $holderKeys as $key ) {
588  list( $ns, $index ) = explode( ':', $key, 2 );
589  $entry =& $this->internals[$ns][$index];
590  $pdbk = $entry['pdbk'];
591 
592  if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
593  // found link in some of the variants, replace the link holder data
594  $entry['title'] = $variantTitle;
595  $entry['pdbk'] = $varPdbk;
596 
597  // set pdbk and colour
598  # @todo FIXME: Convoluted data flow
599  # The redirect status and length is passed to getLinkColour via the LinkCache
600  # Use formal parameters instead
601  $colours[$varPdbk] = Linker::getLinkColour( $variantTitle, $threshold );
602  $linkcolour_ids[$s->page_id] = $pdbk;
603  }
604  }
605 
606  // check if the object is a variant of a category
607  if ( isset( $categoryMap[$vardbk] ) ) {
608  list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
609  if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
610  $varCategories[$oldkey] = $vardbk;
611  }
612  }
613  }
614  Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
615 
616  // rebuild the categories in original order (if there are replacements)
617  if ( count( $varCategories ) > 0 ) {
618  $newCats = [];
619  $originalCats = $output->getCategories();
620  foreach ( $originalCats as $cat => $sortkey ) {
621  // make the replacement
622  if ( array_key_exists( $cat, $varCategories ) ) {
623  $newCats[$varCategories[$cat]] = $sortkey;
624  } else {
625  $newCats[$cat] = $sortkey;
626  }
627  }
628  $output->setCategoryLinks( $newCats );
629  }
630  }
631  }
632 
640  public function replaceText( $text ) {
641 
642  $text = preg_replace_callback(
643  '/<!--(LINK|IWLINK) (.*?)-->/',
644  [ &$this, 'replaceTextCallback' ],
645  $text );
646 
647  return $text;
648  }
649 
657  public function replaceTextCallback( $matches ) {
658  $type = $matches[1];
659  $key = $matches[2];
660  if ( $type == 'LINK' ) {
661  list( $ns, $index ) = explode( ':', $key, 2 );
662  if ( isset( $this->internals[$ns][$index]['text'] ) ) {
663  return $this->internals[$ns][$index]['text'];
664  }
665  } elseif ( $type == 'IWLINK' ) {
666  if ( isset( $this->interwikis[$key]['text'] ) ) {
667  return $this->interwikis[$key]['text'];
668  }
669  }
670  return $matches[0];
671  }
672 }
replace(&$text)
Replace link placeholders with actual links, in the buffer.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1418
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2321
getSubArray($text)
Get a subset of the current LinkHolderArray which is sufficient to interpret the given text...
isBig()
Returns true if the memory requirements of this object are getting large.
$value
static makeSelfLinkObj($nt, $html= '', $query= '', $trail= '', $prefix= '')
Make appropriate markup for a link to the current article.
Definition: Linker.php:409
const NS_SPECIAL
Definition: Defines.php:58
makeHolder($nt, $text= '', $query=[], $trail= '', $prefix= '')
Make a link placeholder.
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:277
doVariants(&$colours)
Modify $this->internals and $colours according to language variant linking rules. ...
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
replaceInterwiki(&$text)
Replace interwiki links.
the value to return A Title object or null for latest to be modified or replaced by the hook handler or if authentication is not possible after cache objects are set for highlighting & $link
Definition: hooks.txt:2581
static splitTrail($trail)
Split a link trail, return the "inside" portion and the remainder of the trail as a two-element array...
Definition: Linker.php:1818
mergeForeign($other, $texts)
Merge a LinkHolderArray from another parser instance into this one.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:31
addInterwikiLink($title)
replaceInternal(&$text)
Replace internal links.
static singleton()
Get an instance of this class.
Definition: LinkCache.php:61
const LIST_AND
Definition: Defines.php:193
Class to perform replacement based on a simple hashtable lookup.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist 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 as context as context $options
Definition: hooks.txt:1004
$res
Definition: database.txt:21
__sleep()
Don't serialize the parent object, it is big, and not needed when it is a parameter to mergeForeign()...
const NS_CATEGORY
Definition: Defines.php:83
static makeTitleSafe($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:548
const DB_SLAVE
Definition: Defines.php:46
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:912
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
setCategoryLinks($cl)
if the prop value should be in the metadata multi language array can modify can modify indexed by page_id & $colours
Definition: hooks.txt:1473
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
__destruct()
Reduce memory usage to reduce the impact of circular references.
static link($target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
Definition: Linker.php:195
const LIST_OR
Definition: Defines.php:196
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist 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 as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object & $output
Definition: hooks.txt:1004
replaceText($text)
Replace link placeholders with plain text of links (not HTML-formatted).
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
__wakeup()
Recreate the Title objects.
clear()
Clear all stored link holders.
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 local content language as $wgContLang
Definition: design.txt:56
addLink(Title $title, $id=null)
Record a local or interwiki inline link for saving in future link tables.
merge($other)
Merge another LinkHolderArray into this one.
$queries
replaceTextCallback($matches)
Callback for replaceText()
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 one of or reset 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:2338
static getLinkColour($t, $threshold)
Return the CSS colour of a known link.
Definition: Linker.php:139
static & makeTitle($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:524
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
Definition: hooks.txt:1798
$matches
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310