MediaWiki  master
TitleTest.php
Go to the documentation of this file.
1 <?php
2 
6 
12  protected function setUp() {
13  parent::setUp();
14 
15  $this->setMwGlobals( [
16  'wgAllowUserJs' => false,
17  'wgDefaultLanguageVariant' => false,
18  'wgMetaNamespace' => 'Project',
19  ] );
20  $this->setUserLang( 'en' );
21  $this->setContentLang( 'en' );
22  }
23 
24  protected function tearDown() {
25  // For testNewMainPage
27  parent::tearDown();
28  }
29 
33  public function testLegalChars() {
34  $titlechars = Title::legalChars();
35 
36  foreach ( range( 1, 255 ) as $num ) {
37  $chr = chr( $num );
38  if ( strpos( "#[]{}<>|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) {
39  $this->assertFalse(
40  (bool)preg_match( "/[$titlechars]/", $chr ),
41  "chr($num) = $chr is not a valid titlechar"
42  );
43  } else {
44  $this->assertTrue(
45  (bool)preg_match( "/[$titlechars]/", $chr ),
46  "chr($num) = $chr is a valid titlechar"
47  );
48  }
49  }
50  }
51 
52  public static function provideValidSecureAndSplit() {
53  return [
54  [ 'Sandbox' ],
55  [ 'A "B"' ],
56  [ 'A \'B\'' ],
57  [ '.com' ],
58  [ '~' ],
59  [ '#' ],
60  [ '"' ],
61  [ '\'' ],
62  [ 'Talk:Sandbox' ],
63  [ 'Talk:Foo:Sandbox' ],
64  [ 'File:Example.svg' ],
65  [ 'File_talk:Example.svg' ],
66  [ 'Foo/.../Sandbox' ],
67  [ 'Sandbox/...' ],
68  [ 'A~~' ],
69  [ ':A' ],
70  // Length is 256 total, but only title part matters
71  [ 'Category:' . str_repeat( 'x', 248 ) ],
72  [ str_repeat( 'x', 252 ) ],
73  // interwiki prefix
74  [ 'localtestiw: #anchor' ],
75  [ 'localtestiw:' ],
76  [ 'localtestiw:foo' ],
77  [ 'localtestiw: foo # anchor' ],
78  [ 'localtestiw: Talk: Sandbox # anchor' ],
79  [ 'remotetestiw:' ],
80  [ 'remotetestiw: Talk: # anchor' ],
81  [ 'remotetestiw: #bar' ],
82  [ 'remotetestiw: Talk:' ],
83  [ 'remotetestiw: Talk: Foo' ],
84  [ 'localtestiw:remotetestiw:' ],
85  [ 'localtestiw:remotetestiw:foo' ]
86  ];
87  }
88 
89  public static function provideInvalidSecureAndSplit() {
90  return [
91  [ '', 'title-invalid-empty' ],
92  [ ':', 'title-invalid-empty' ],
93  [ '__ __', 'title-invalid-empty' ],
94  [ ' __ ', 'title-invalid-empty' ],
95  // Bad characters forbidden regardless of wgLegalTitleChars
96  [ 'A [ B', 'title-invalid-characters' ],
97  [ 'A ] B', 'title-invalid-characters' ],
98  [ 'A { B', 'title-invalid-characters' ],
99  [ 'A } B', 'title-invalid-characters' ],
100  [ 'A < B', 'title-invalid-characters' ],
101  [ 'A > B', 'title-invalid-characters' ],
102  [ 'A | B', 'title-invalid-characters' ],
103  [ "A \t B", 'title-invalid-characters' ],
104  [ "A \n B", 'title-invalid-characters' ],
105  // URL encoding
106  [ 'A%20B', 'title-invalid-characters' ],
107  [ 'A%23B', 'title-invalid-characters' ],
108  [ 'A%2523B', 'title-invalid-characters' ],
109  // XML/HTML character entity references
110  // Note: Commented out because they are not marked invalid by the PHP test as
111  // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
112  // 'A &eacute; B',
113  // 'A &#233; B',
114  // 'A &#x00E9; B',
115  // Subject of NS_TALK does not roundtrip to NS_MAIN
116  [ 'Talk:File:Example.svg', 'title-invalid-talk-namespace' ],
117  // Directory navigation
118  [ '.', 'title-invalid-relative' ],
119  [ '..', 'title-invalid-relative' ],
120  [ './Sandbox', 'title-invalid-relative' ],
121  [ '../Sandbox', 'title-invalid-relative' ],
122  [ 'Foo/./Sandbox', 'title-invalid-relative' ],
123  [ 'Foo/../Sandbox', 'title-invalid-relative' ],
124  [ 'Sandbox/.', 'title-invalid-relative' ],
125  [ 'Sandbox/..', 'title-invalid-relative' ],
126  // Tilde
127  [ 'A ~~~ Name', 'title-invalid-magic-tilde' ],
128  [ 'A ~~~~ Signature', 'title-invalid-magic-tilde' ],
129  [ 'A ~~~~~ Timestamp', 'title-invalid-magic-tilde' ],
130  // Length
131  [ str_repeat( 'x', 256 ), 'title-invalid-too-long' ],
132  // Namespace prefix without actual title
133  [ 'Talk:', 'title-invalid-empty' ],
134  [ 'Talk:#', 'title-invalid-empty' ],
135  [ 'Category: ', 'title-invalid-empty' ],
136  [ 'Category: #bar', 'title-invalid-empty' ],
137  // interwiki prefix
138  [ 'localtestiw: Talk: # anchor', 'title-invalid-empty' ],
139  [ 'localtestiw: Talk:', 'title-invalid-empty' ]
140  ];
141  }
142 
143  private function secureAndSplitGlobals() {
144  $this->setMwGlobals( [
145  'wgLocalInterwikis' => [ 'localtestiw' ],
146  'wgHooks' => [
147  'InterwikiLoadPrefix' => [
148  function ( $prefix, &$data ) {
149  if ( $prefix === 'localtestiw' ) {
150  $data = [ 'iw_url' => 'localtestiw' ];
151  } elseif ( $prefix === 'remotetestiw' ) {
152  $data = [ 'iw_url' => 'remotetestiw' ];
153  }
154  return false;
155  }
156  ]
157  ]
158  ] );
159 
160  // Reset services since we modified $wgLocalInterwikis
161  $this->overrideMwServices();
162  }
163 
170  public function testSecureAndSplitValid( $text ) {
171  $this->secureAndSplitGlobals();
172  $this->assertInstanceOf( Title::class, Title::newFromText( $text ), "Valid: $text" );
173  }
174 
181  public function testSecureAndSplitInvalid( $text, $expectedErrorMessage ) {
182  $this->secureAndSplitGlobals();
183  try {
184  Title::newFromTextThrow( $text ); // should throw
185  $this->assertTrue( false, "Invalid: $text" );
186  } catch ( MalformedTitleException $ex ) {
187  $this->assertEquals( $expectedErrorMessage, $ex->getErrorMessage(), "Invalid: $text" );
188  }
189  }
190 
191  public static function provideConvertByteClassToUnicodeClass() {
192  return [
193  [
194  ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+',
195  ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF',
196  ],
197  [
198  'QWERTYf-\\xFF+',
199  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
200  ],
201  [
202  'QWERTY\\x66-\\xFD+',
203  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
204  ],
205  [
206  'QWERTYf-y+',
207  'QWERTYf-y+',
208  ],
209  [
210  'QWERTYf-\\x80+',
211  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
212  ],
213  [
214  'QWERTY\\x66-\\x80+\\x23',
215  'QWERTYf-\\x7F+#\\u0080-\\uFFFF',
216  ],
217  [
218  'QWERTY\\x66-\\x80+\\xD3',
219  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
220  ],
221  [
222  '\\\\\\x99',
223  '\\\\\\u0080-\\uFFFF',
224  ],
225  [
226  '-\\x99',
227  '\\-\\u0080-\\uFFFF',
228  ],
229  [
230  'QWERTY\\-\\x99',
231  'QWERTY\\-\\u0080-\\uFFFF',
232  ],
233  [
234  '\\\\x99',
235  '\\\\x99',
236  ],
237  [
238  'A-\\x9F',
239  'A-\\x7F\\u0080-\\uFFFF',
240  ],
241  [
242  '\\x66-\\x77QWERTY\\x88-\\x91FXZ',
243  'f-wQWERTYFXZ\\u0080-\\uFFFF',
244  ],
245  [
246  '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ',
247  'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF',
248  ],
249  ];
250  }
251 
256  public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) {
257  $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) );
258  }
259 
264  public function testFixSpecialNameRetainsParameter( $text, $expectedParam ) {
265  $title = Title::newFromText( $text );
266  $fixed = $title->fixSpecialName();
267  $stuff = explode( '/', $fixed->getDBkey(), 2 );
268  if ( count( $stuff ) == 2 ) {
269  $par = $stuff[1];
270  } else {
271  $par = null;
272  }
273  $this->assertEquals(
274  $expectedParam,
275  $par,
276  "T33100 regression check: Title->fixSpecialName() should preserve parameter"
277  );
278  }
279 
281  return [
282  [ 'Special:Version', null ],
283  [ 'Special:Version/', '' ],
284  [ 'Special:Version/param', 'param' ],
285  ];
286  }
287 
297  public function testIsValidMoveOperation( $source, $target, $expected ) {
298  $this->hideDeprecated( 'Title::isValidMoveOperation' );
299 
300  $this->setMwGlobals( 'wgContentHandlerUseDB', false );
302  $nt = Title::newFromText( $target );
303  $errors = $title->isValidMoveOperation( $nt, false );
304  if ( $expected === true ) {
305  $this->assertTrue( $errors );
306  } else {
307  $errors = $this->flattenErrorsArray( $errors );
308  foreach ( (array)$expected as $error ) {
309  $this->assertContains( $error, $errors );
310  }
311  }
312  }
313 
314  public static function provideTestIsValidMoveOperation() {
315  return [
316  // for Title::isValidMoveOperation
317  [ 'Some page', '', 'badtitletext' ],
318  [ 'Test', 'Test', 'selfmove' ],
319  [ 'Special:FooBar', 'Test', 'immobile-source-namespace' ],
320  [ 'Test', 'Special:FooBar', 'immobile-target-namespace' ],
321  [ 'MediaWiki:Common.js', 'Help:Some wikitext page', 'bad-target-model' ],
322  [ 'Page', 'File:Test.jpg', 'nonfile-cannot-move-to-file' ],
323  [ 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ],
324  ];
325  }
326 
338  public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
339  // $wgWhitelistReadRegexp must be an array. Since the provided test cases
340  // usually have only one regex, it is more concise to write the lonely regex
341  // as a string. Thus we cast to a [] to honor $wgWhitelistReadRegexp
342  // type requisite.
343  if ( is_string( $whitelistRegexp ) ) {
344  $whitelistRegexp = [ $whitelistRegexp ];
345  }
346 
347  $this->setMwGlobals( [
348  // So User::isEveryoneAllowed( 'read' ) === false
349  'wgGroupPermissions' => [ '*' => [ 'read' => false ] ],
350  'wgWhitelistRead' => [ 'some random non sense title' ],
351  'wgWhitelistReadRegexp' => $whitelistRegexp,
352  ] );
353 
355 
356  // New anonymous user with no rights
357  $user = new User;
358  $user->mRights = [];
359  $errors = $title->userCan( $action, $user );
360 
361  if ( is_bool( $expected ) ) {
362  # Forge the assertion message depending on the assertion expectation
363  $allowableness = $expected
364  ? " should be allowed"
365  : " should NOT be allowed";
366  $this->assertEquals(
367  $expected,
368  $errors,
369  "User action '$action' on [[$source]] $allowableness."
370  );
371  } else {
372  $errors = $this->flattenErrorsArray( $errors );
373  foreach ( (array)$expected as $error ) {
374  $this->assertContains( $error, $errors );
375  }
376  }
377  }
378 
382  public function dataWgWhitelistReadRegexp() {
383  $ALLOWED = true;
384  $DISALLOWED = false;
385 
386  return [
387  // Everything, if this doesn't work, we're really in trouble
388  [ '/.*/', 'Main_Page', 'read', $ALLOWED ],
389  [ '/.*/', 'Main_Page', 'edit', $DISALLOWED ],
390 
391  // We validate against the title name, not the db key
392  [ '/^Main_Page$/', 'Main_Page', 'read', $DISALLOWED ],
393  // Main page
394  [ '/^Main/', 'Main_Page', 'read', $ALLOWED ],
395  [ '/^Main.*/', 'Main_Page', 'read', $ALLOWED ],
396  // With spaces
397  [ '/Mic\sCheck/', 'Mic Check', 'read', $ALLOWED ],
398  // Unicode multibyte
399  // ...without unicode modifier
400  [ '/Unicode Test . Yes/', 'Unicode Test Ñ Yes', 'read', $DISALLOWED ],
401  // ...with unicode modifier
402  [ '/Unicode Test . Yes/u', 'Unicode Test Ñ Yes', 'read', $ALLOWED ],
403  // Case insensitive
404  [ '/MiC ChEcK/', 'mic check', 'read', $DISALLOWED ],
405  [ '/MiC ChEcK/i', 'mic check', 'read', $ALLOWED ],
406 
407  // From DefaultSettings.php:
408  [ "@^UsEr.*@i", 'User is banned', 'read', $ALLOWED ],
409  [ "@^UsEr.*@i", 'User:John Doe', 'read', $ALLOWED ],
410 
411  // With namespaces:
412  [ '/^Special:NewPages$/', 'Special:NewPages', 'read', $ALLOWED ],
413  [ null, 'Special:Newpages', 'read', $DISALLOWED ],
414 
415  ];
416  }
417 
418  public function flattenErrorsArray( $errors ) {
419  $result = [];
420  foreach ( $errors as $error ) {
421  $result[] = $error[0];
422  }
423 
424  return $result;
425  }
426 
431  public function testGetPageViewLanguage( $expected, $titleText, $contLang,
432  $lang, $variant, $msg = ''
433  ) {
434  // Setup environnement for this test
435  $this->setMwGlobals( [
436  'wgDefaultLanguageVariant' => $variant,
437  'wgAllowUserJs' => true,
438  ] );
439  $this->setUserLang( $lang );
440  $this->setContentLang( $contLang );
441 
442  $title = Title::newFromText( $titleText );
443  $this->assertInstanceOf( Title::class, $title,
444  "Test must be passed a valid title text, you gave '$titleText'"
445  );
446  $this->assertEquals( $expected,
447  $title->getPageViewLanguage()->getCode(),
448  $msg
449  );
450  }
451 
452  public static function provideGetPageViewLanguage() {
453  # Format:
454  # - expected
455  # - Title name
456  # - content language (expected in most cases)
457  # - wgLang (on some specific pages)
458  # - wgDefaultLanguageVariant
459  # - Optional message
460  return [
461  [ 'fr', 'Help:I_need_somebody', 'fr', 'fr', false ],
462  [ 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ],
463  [ 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ],
464 
465  [ 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ],
466  [ 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ],
467  [ 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ],
468  [ 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ],
469  [ 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ],
470  [ 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ],
471  [ 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ],
472  [ 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ],
473 
474  [ 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ],
475  [ 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ],
476  [ 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ],
477  [ 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ],
478  [ 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ],
479  [ 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ],
480  [ 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ],
481  [ 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ],
482  [ 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ],
483  [ 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ],
484 
485  [ 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ],
486  [ 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ],
487 
488  ];
489  }
490 
495  public function testGetBaseText( $title, $expected, $msg = '' ) {
497  $this->assertEquals( $expected,
498  $title->getBaseText(),
499  $msg
500  );
501  }
502 
503  public static function provideBaseTitleCases() {
504  return [
505  # Title, expected base, optional message
506  [ 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ],
507  [ 'User:Foo/Bar/Baz', 'Foo/Bar' ],
508  ];
509  }
510 
515  public function testGetRootText( $title, $expected, $msg = '' ) {
517  $this->assertEquals( $expected,
518  $title->getRootText(),
519  $msg
520  );
521  }
522 
523  public static function provideRootTitleCases() {
524  return [
525  # Title, expected base, optional message
526  [ 'User:John_Doe/subOne/subTwo', 'John Doe' ],
527  [ 'User:Foo/Bar/Baz', 'Foo' ],
528  ];
529  }
530 
536  public function testGetSubpageText( $title, $expected, $msg = '' ) {
538  $this->assertEquals( $expected,
539  $title->getSubpageText(),
540  $msg
541  );
542  }
543 
544  public static function provideSubpageTitleCases() {
545  return [
546  # Title, expected base, optional message
547  [ 'User:John_Doe/subOne/subTwo', 'subTwo' ],
548  [ 'User:John_Doe/subOne', 'subOne' ],
549  ];
550  }
551 
552  public static function provideNewFromTitleValue() {
553  return [
554  [ new TitleValue( NS_MAIN, 'Foo' ) ],
555  [ new TitleValue( NS_MAIN, 'Foo', 'bar' ) ],
556  [ new TitleValue( NS_USER, 'Hansi_Maier' ) ],
557  ];
558  }
559 
565  $title = Title::newFromTitleValue( $value );
566 
567  $dbkey = str_replace( ' ', '_', $value->getText() );
568  $this->assertEquals( $dbkey, $title->getDBkey() );
569  $this->assertEquals( $value->getNamespace(), $title->getNamespace() );
570  $this->assertEquals( $value->getFragment(), $title->getFragment() );
571  }
572 
578  $title = Title::newFromLinkTarget( $value );
579 
580  $dbkey = str_replace( ' ', '_', $value->getText() );
581  $this->assertEquals( $dbkey, $title->getDBkey() );
582  $this->assertEquals( $value->getNamespace(), $title->getNamespace() );
583  $this->assertEquals( $value->getFragment(), $title->getFragment() );
584  }
585 
589  public function testNewFromLinkTarget_clone() {
590  $title = Title::newFromText( __METHOD__ );
591  $this->assertSame( $title, Title::newFromLinkTarget( $title ) );
592 
593  // The Title::NEW_CLONE flag should ensure that a fresh instance is returned.
595  $this->assertNotSame( $title, $clone );
596  $this->assertTrue( $clone->equals( $title ) );
597  }
598 
599  public function provideCastFromLinkTarget() {
600  return array_merge( [ [ null ] ], self::provideNewFromTitleValue() );
601  }
602 
607  public function testCastFromLinkTarget( $value ) {
609 
610  if ( $value === null ) {
611  $this->assertNull( $title );
612  } else {
613  $dbkey = str_replace( ' ', '_', $value->getText() );
614  $this->assertSame( $dbkey, $title->getDBkey() );
615  $this->assertSame( $value->getNamespace(), $title->getNamespace() );
616  $this->assertSame( $value->getFragment(), $title->getFragment() );
617  }
618  }
619 
620  public static function provideGetTitleValue() {
621  return [
622  [ 'Foo' ],
623  [ 'Foo#bar' ],
624  [ 'User:Hansi_Maier' ],
625  ];
626  }
627 
632  public function testGetTitleValue( $text ) {
633  $title = Title::newFromText( $text );
634  $value = $title->getTitleValue();
635 
636  $dbkey = str_replace( ' ', '_', $value->getText() );
637  $this->assertEquals( $title->getDBkey(), $dbkey );
638  $this->assertEquals( $title->getNamespace(), $value->getNamespace() );
639  $this->assertEquals( $title->getFragment(), $value->getFragment() );
640  }
641 
642  public static function provideGetFragment() {
643  return [
644  [ 'Foo', '' ],
645  [ 'Foo#bar', 'bar' ],
646  [ 'Foo#bär', 'bär' ],
647 
648  // Inner whitespace is normalized
649  [ 'Foo#bar_bar', 'bar bar' ],
650  [ 'Foo#bar bar', 'bar bar' ],
651  [ 'Foo#bar bar', 'bar bar' ],
652 
653  // Leading whitespace is kept, trailing whitespace is trimmed.
654  // XXX: Is this really want we want?
655  [ 'Foo#_bar_bar_', ' bar bar' ],
656  [ 'Foo# bar bar ', ' bar bar' ],
657  ];
658  }
659 
667  public function testGetFragment( $full, $fragment ) {
668  $title = Title::newFromText( $full );
669  $this->assertEquals( $fragment, $title->getFragment() );
670  }
671 
678  public function testIsAlwaysKnown( $page, $isKnown ) {
679  $title = Title::newFromText( $page );
680  $this->assertEquals( $isKnown, $title->isAlwaysKnown() );
681  }
682 
683  public static function provideIsAlwaysKnown() {
684  return [
685  [ 'Some nonexistent page', false ],
686  [ 'UTPage', false ],
687  [ '#test', true ],
688  [ 'Special:BlankPage', true ],
689  [ 'Special:SomeNonexistentSpecialPage', false ],
690  [ 'MediaWiki:Parentheses', true ],
691  [ 'MediaWiki:Some nonexistent message', false ],
692  ];
693  }
694 
701  public function testIsValid( Title $title, $isValid ) {
702  $this->assertEquals( $isValid, $title->isValid(), $title->getPrefixedText() );
703  }
704 
705  public static function provideIsValid() {
706  return [
707  [ Title::makeTitle( NS_MAIN, '' ), false ],
708  [ Title::makeTitle( NS_MAIN, '<>' ), false ],
709  [ Title::makeTitle( NS_MAIN, '|' ), false ],
710  [ Title::makeTitle( NS_MAIN, '#' ), false ],
711  [ Title::makeTitle( NS_MAIN, 'Test' ), true ],
712  [ Title::makeTitle( -33, 'Test' ), false ],
713  [ Title::makeTitle( 77663399, 'Test' ), false ],
714  ];
715  }
716 
720  public function testIsAlwaysKnownOnInterwiki() {
721  $title = Title::makeTitle( NS_MAIN, 'Interwiki link', '', 'externalwiki' );
722  $this->assertTrue( $title->isAlwaysKnown() );
723  }
724 
728  public function testExists() {
729  $title = Title::makeTitle( NS_PROJECT, 'New page' );
730  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
731 
732  $article = new Article( $title );
733  $page = $article->getPage();
734  $page->doEditContent( new WikitextContent( 'Some [[link]]' ), 'summary' );
735 
736  // Tell Title it doesn't know whether it exists
737  $title->mArticleID = -1;
738 
739  // Tell the link cache it doesn't exists when it really does
740  $linkCache->clearLink( $title );
741  $linkCache->addBadLinkObj( $title );
742 
743  $this->assertEquals(
744  false,
745  $title->exists(),
746  'exists() should rely on link cache unless GAID_FOR_UPDATE is used'
747  );
748  $this->assertEquals(
749  true,
750  $title->exists( Title::GAID_FOR_UPDATE ),
751  'exists() should re-query database when GAID_FOR_UPDATE is used'
752  );
753  }
754 
755  public function provideCanHaveTalkPage() {
756  return [
757  'User page has talk page' => [
758  Title::makeTitle( NS_USER, 'Jane' ), true
759  ],
760  'Talke page has talk page' => [
761  Title::makeTitle( NS_TALK, 'Foo' ), true
762  ],
763  'Special page cannot have talk page' => [
764  Title::makeTitle( NS_SPECIAL, 'Thing' ), false
765  ],
766  'Virtual namespace cannot have talk page' => [
767  Title::makeTitle( NS_MEDIA, 'Kitten.jpg' ), false
768  ],
769  ];
770  }
771 
779  public function testCanHaveTalkPage( Title $title, $expected ) {
780  $actual = $title->canHaveTalkPage();
781  $this->assertSame( $expected, $actual, $title->getPrefixedDBkey() );
782  }
783 
784  public static function provideGetTalkPage_good() {
785  return [
786  [ Title::makeTitle( NS_MAIN, 'Test' ), Title::makeTitle( NS_TALK, 'Test' ) ],
787  [ Title::makeTitle( NS_TALK, 'Test' ), Title::makeTitle( NS_TALK, 'Test' ) ],
788  ];
789  }
790 
796  $talk = $title->getTalkPageIfDefined();
797  $this->assertInstanceOf(
798  Title::class,
799  $talk,
800  $title->getPrefixedDBKey()
801  );
802  }
803 
804  public static function provideGetTalkPage_bad() {
805  return [
806  [ Title::makeTitle( NS_SPECIAL, 'Test' ) ],
807  [ Title::makeTitle( NS_MEDIA, 'Test' ) ],
808  ];
809  }
810 
816  $talk = $title->getTalkPageIfDefined();
817  $this->assertNull(
818  $talk,
819  $title->getPrefixedDBKey()
820  );
821  }
822 
823  public function provideCreateFragmentTitle() {
824  return [
825  [ Title::makeTitle( NS_MAIN, 'Test' ), 'foo' ],
826  [ Title::makeTitle( NS_TALK, 'Test', 'foo' ), '' ],
827  [ Title::makeTitle( NS_CATEGORY, 'Test', 'foo' ), 'bar' ],
828  [ Title::makeTitle( NS_MAIN, 'Test1', '', 'interwiki' ), 'baz' ]
829  ];
830  }
831 
836  public function testCreateFragmentTitle( Title $title, $fragment ) {
837  $this->mergeMwGlobalArrayValue( 'wgHooks', [
838  'InterwikiLoadPrefix' => [
839  function ( $prefix, &$iwdata ) {
840  if ( $prefix === 'interwiki' ) {
841  $iwdata = [
842  'iw_url' => 'http://example.com/',
843  'iw_local' => 0,
844  'iw_trans' => 0,
845  ];
846  return false;
847  }
848  },
849  ],
850  ] );
851 
852  $fragmentTitle = $title->createFragmentTarget( $fragment );
853 
854  $this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
855  $this->assertEquals( $title->getText(), $fragmentTitle->getText() );
856  $this->assertEquals( $title->getInterwiki(), $fragmentTitle->getInterwiki() );
857  $this->assertEquals( $fragment, $fragmentTitle->getFragment() );
858  }
859 
860  public function provideGetPrefixedText() {
861  return [
862  // ns = 0
863  [
864  Title::makeTitle( NS_MAIN, 'Foo bar' ),
865  'Foo bar'
866  ],
867  // ns = 2
868  [
869  Title::makeTitle( NS_USER, 'Foo bar' ),
870  'User:Foo bar'
871  ],
872  // ns = 3
873  [
874  Title::makeTitle( NS_USER_TALK, 'Foo bar' ),
875  'User talk:Foo bar'
876  ],
877  // fragment not included
878  [
879  Title::makeTitle( NS_MAIN, 'Foo bar', 'fragment' ),
880  'Foo bar'
881  ],
882  // ns = -2
883  [
884  Title::makeTitle( NS_MEDIA, 'Foo bar' ),
885  'Media:Foo bar'
886  ],
887  // non-existent namespace
888  [
889  Title::makeTitle( 100777, 'Foo bar' ),
890  'Special:Badtitle/NS100777:Foo bar'
891  ],
892  ];
893  }
894 
899  public function testGetPrefixedText( Title $title, $expected ) {
900  $this->assertEquals( $expected, $title->getPrefixedText() );
901  }
902 
903  public function provideGetPrefixedDBKey() {
904  return [
905  // ns = 0
906  [
907  Title::makeTitle( NS_MAIN, 'Foo_bar' ),
908  'Foo_bar'
909  ],
910  // ns = 2
911  [
912  Title::makeTitle( NS_USER, 'Foo_bar' ),
913  'User:Foo_bar'
914  ],
915  // ns = 3
916  [
917  Title::makeTitle( NS_USER_TALK, 'Foo_bar' ),
918  'User_talk:Foo_bar'
919  ],
920  // fragment not included
921  [
922  Title::makeTitle( NS_MAIN, 'Foo_bar', 'fragment' ),
923  'Foo_bar'
924  ],
925  // ns = -2
926  [
927  Title::makeTitle( NS_MEDIA, 'Foo_bar' ),
928  'Media:Foo_bar'
929  ],
930  // non-existent namespace
931  [
932  Title::makeTitle( 100777, 'Foo_bar' ),
933  'Special:Badtitle/NS100777:Foo_bar'
934  ],
935  ];
936  }
937 
942  public function testGetPrefixedDBKey( Title $title, $expected ) {
943  $this->assertEquals( $expected, $title->getPrefixedDBkey() );
944  }
945 
953  public function testGetFragmentForURL( $titleStr, $expected ) {
954  $this->setMwGlobals( [
955  'wgFragmentMode' => [ 'html5' ],
956  'wgExternalInterwikiFragmentMode' => 'legacy',
957  ] );
958  $dbw = wfGetDB( DB_MASTER );
959  $dbw->insert( 'interwiki',
960  [
961  [
962  'iw_prefix' => 'de',
963  'iw_url' => 'http://de.wikipedia.org/wiki/',
964  'iw_api' => 'http://de.wikipedia.org/w/api.php',
965  'iw_wikiid' => 'dewiki',
966  'iw_local' => 1,
967  'iw_trans' => 0,
968  ],
969  [
970  'iw_prefix' => 'zz',
971  'iw_url' => 'http://zzwiki.org/wiki/',
972  'iw_api' => 'http://zzwiki.org/w/api.php',
973  'iw_wikiid' => 'zzwiki',
974  'iw_local' => 0,
975  'iw_trans' => 0,
976  ],
977  ],
978  __METHOD__,
979  [ 'IGNORE' ]
980  );
981 
982  $title = Title::newFromText( $titleStr );
983  self::assertEquals( $expected, $title->getFragmentForURL() );
984 
985  $dbw->delete( 'interwiki', '*', __METHOD__ );
986  }
987 
988  public function provideGetFragmentForURL() {
989  return [
990  [ 'Foo', '' ],
991  [ 'Foo#ümlåût', '#ümlåût' ],
992  [ 'de:Foo#Bå®', '#Bå®' ],
993  [ 'zz:Foo#тест', '#.D1.82.D0.B5.D1.81.D1.82' ],
994  ];
995  }
996 
1001  public function testIsRawHtmlMessage( $textForm, $expected ) {
1002  $this->setMwGlobals( 'wgRawHtmlMessages', [
1003  'foobar',
1004  'foo_bar',
1005  'foo-bar',
1006  ] );
1007 
1008  $title = Title::newFromText( $textForm );
1009  $this->assertSame( $expected, $title->isRawHtmlMessage() );
1010  }
1011 
1012  public function provideIsRawHtmlMessage() {
1013  return [
1014  [ 'MediaWiki:Foobar', true ],
1015  [ 'MediaWiki:Foo bar', true ],
1016  [ 'MediaWiki:Foo-bar', true ],
1017  [ 'MediaWiki:foo bar', true ],
1018  [ 'MediaWiki:foo-bar', true ],
1019  [ 'MediaWiki:foobar', true ],
1020  [ 'MediaWiki:some-other-message', false ],
1021  [ 'Main Page', false ],
1022  ];
1023  }
1024 
1025  public function provideEquals() {
1026  yield [
1027  Title::newFromText( 'Main Page' ),
1028  Title::newFromText( 'Main Page' ),
1029  true
1030  ];
1031  yield [
1032  Title::newFromText( 'Main Page' ),
1033  Title::newFromText( 'Not The Main Page' ),
1034  false
1035  ];
1036  yield [
1037  Title::newFromText( 'Main Page' ),
1038  Title::newFromText( 'Project:Main Page' ),
1039  false
1040  ];
1041  yield [
1042  Title::newFromText( 'File:Example.png' ),
1043  Title::newFromText( 'Image:Example.png' ),
1044  true
1045  ];
1046  yield [
1047  Title::newFromText( 'Special:Version' ),
1048  Title::newFromText( 'Special:Version' ),
1049  true
1050  ];
1051  yield [
1052  Title::newFromText( 'Special:Version' ),
1053  Title::newFromText( 'Special:Recentchanges' ),
1054  false
1055  ];
1056  yield [
1057  Title::newFromText( 'Special:Version' ),
1058  Title::newFromText( 'Main Page' ),
1059  false
1060  ];
1061  yield [
1062  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1063  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1064  true
1065  ];
1066  yield [
1067  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1068  Title::makeTitle( NS_MAIN, 'Bar', '', '' ),
1069  false
1070  ];
1071  yield [
1072  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1073  Title::makeTitle( NS_TALK, 'Foo', '', '' ),
1074  false
1075  ];
1076  yield [
1077  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1078  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1079  true
1080  ];
1081  yield [
1082  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1083  Title::makeTitle( NS_MAIN, 'Foo', 'Baz', '' ),
1084  true
1085  ];
1086  yield [
1087  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1088  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1089  true
1090  ];
1091  yield [
1092  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1093  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1094  true
1095  ];
1096  yield [
1097  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1098  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1099  false
1100  ];
1101  }
1102 
1107  public function testEquals( Title $firstValue, /* LinkTarget */ $secondValue, $expectedSame ) {
1108  $this->assertSame(
1109  $expectedSame,
1110  $firstValue->equals( $secondValue )
1111  );
1112  }
1113 
1117  public function testNewMainPage() {
1118  $msgCache = TestingAccessWrapper::newFromClass( MessageCache::class );
1119  $msgCache->instance = $this->createMock( MessageCache::class );
1120  $msgCache->instance->method( 'get' )->willReturn( 'Foresheet' );
1121  $msgCache->instance->method( 'transform' )->willReturn( 'Foresheet' );
1122 
1123  $this->assertSame(
1124  'Foresheet',
1125  Title::newMainPage()->getText()
1126  );
1127  }
1128 
1132  public function testNewMainPageWithLocal() {
1133  $local = $this->createMock( MessageLocalizer::class );
1134  $local->method( 'msg' )->willReturn( new RawMessage( 'Prime Article' ) );
1135 
1136  $this->assertSame(
1137  'Prime Article',
1138  Title::newMainPage( $local )->getText()
1139  );
1140  }
1141 }
getText()
Returns the title in text form, without namespace prefix or fragment.
Definition: TitleValue.php:171
testIsValidMoveOperation( $source, $target, $expected)
Auth-less test of Title::isValidMoveOperation.
Definition: TitleTest.php:297
static castFromLinkTarget( $linkTarget)
Same as newFromLinkTarget, but if passed null, returns null.
Definition: Title.php:295
testSecureAndSplitValid( $text)
See also mediawiki.Title.test.js Title::secureAndSplit provideValidSecureAndSplit.
Definition: TitleTest.php:170
testIsAlwaysKnownOnInterwiki()
Title::isAlwaysKnown.
Definition: TitleTest.php:720
canHaveTalkPage()
Can this title have a corresponding talk page?
Definition: Title.php:1136
static provideGetPageViewLanguage()
Definition: TitleTest.php:452
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
static provideValidSecureAndSplit()
Definition: TitleTest.php:52
testFixSpecialNameRetainsParameter( $text, $expectedParam)
provideSpecialNamesWithAndWithoutParameter Title::fixSpecialName
Definition: TitleTest.php:264
testEquals(Title $firstValue, $secondValue, $expectedSame)
Title::equals provideEquals.
Definition: TitleTest.php:1107
const NS_MAIN
Definition: Defines.php:60
getText()
Get the text form (spaces not underscores) of the main part.
Definition: Title.php:984
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:653
static provideSpecialNamesWithAndWithoutParameter()
Definition: TitleTest.php:280
testIsAlwaysKnown( $page, $isKnown)
Title::isAlwaysKnown provideIsAlwaysKnown.
Definition: TitleTest.php:678
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
static provideGetFragment()
Definition: TitleTest.php:642
equals(LinkTarget $title)
Compare with another title.
Definition: Title.php:3985
getTalkPageIfDefined()
Get a Title object associated with the talk page of this article, if such a talk page can exist...
Definition: Title.php:1535
if(!isset( $args[0])) $lang
static destroyInstance()
Destroy the singleton instance.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected)
Auth-less test of Title::userCan.
Definition: TitleTest.php:338
Class for viewing MediaWiki article and history.
Definition: Article.php:38
$source
$value
static provideIsValid()
Definition: TitleTest.php:705
const NS_SPECIAL
Definition: Defines.php:49
static provideConvertByteClassToUnicodeClass()
Definition: TitleTest.php:191
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
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1696
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
secureAndSplitGlobals()
Definition: TitleTest.php:143
testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass)
provideConvertByteClassToUnicodeClass Title::convertByteClassToUnicodeClass
Definition: TitleTest.php:256
static provideRootTitleCases()
Definition: TitleTest.php:523
testIsValid(Title $title, $isValid)
Title::isValid provideIsValid.
Definition: TitleTest.php:701
const DB_MASTER
Definition: defines.php:26
static provideSubpageTitleCases()
Definition: TitleTest.php:544
static provideNewFromTitleValue()
Definition: TitleTest.php:552
testGetRootText( $title, $expected, $msg='')
provideRootTitleCases Title::getRootText
Definition: TitleTest.php:515
getNamespace()
Get the namespace index.
static provideBaseTitleCases()
Definition: TitleTest.php:503
const NEW_CLONE
Flag for use with factory methods like newFromLinkTarget() that have a $forceClone parameter...
Definition: Title.php:64
static provideTestIsValidMoveOperation()
Definition: TitleTest.php:314
provideGetPrefixedText()
Definition: TitleTest.php:860
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page. Return false to stop further processing of the tag $reader:XMLReader object & $pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUnknownUser':When a user doesn 't exist locally, this hook is called to give extensions an opportunity to auto-create it. If the auto-creation is successful, return false. $name:User name 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports. & $fullInterwikiPrefix:Interwiki prefix, may contain colons. & $pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable. Can be used to lazy-load the import sources list. & $importSources:The value of $wgImportSources. Modify as necessary. See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. & $title:Title object for the current page & $request:WebRequest & $ignoreRedirect:boolean to skip redirect check & $target:Title/string of redirect target & $article:Article object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) & $article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() & $ip:IP being check & $result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Array with elements of the form "language:title" in the order that they will be output. & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LanguageSelector':Hook to change the language selector available on a page. $out:The output page. $cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED since 1.28! Use HtmlPageLinkRendererBegin instead. Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1980
static convertByteClassToUnicodeClass( $byteClass)
Utility method for converting a character sequence from bytes to Unicode.
Definition: Title.php:714
getFragment()
Get the link fragment (i.e.
testGetPrefixedDBKey(Title $title, $expected)
Title::getPrefixedDBKey provideGetPrefixedDBKey.
Definition: TitleTest.php:942
testGetBaseText( $title, $expected, $msg='')
provideBaseTitleCases Title::getBaseText
Definition: TitleTest.php:495
testExists()
Title::exists.
Definition: TitleTest.php:728
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 true
Definition: hooks.txt:1982
testGetFragmentForURL( $titleStr, $expected)
Title::getFragmentForURL provideGetFragmentForURL.
Definition: TitleTest.php:953
Database Title.
Definition: TitleTest.php:11
const NS_PROJECT
Definition: Defines.php:64
testNewMainPageWithLocal()
Title::newMainPage.
Definition: TitleTest.php:1132
testGetTalkPageIfDefined_bad(Title $title)
provideGetTalkPage_bad Title::getTalkPageIfDefined
Definition: TitleTest.php:815
const NS_MEDIA
Definition: Defines.php:48
const GAID_FOR_UPDATE
Used to be GAID_FOR_UPDATE define.
Definition: Title.php:55
flattenErrorsArray( $errors)
Definition: TitleTest.php:418
const NS_CATEGORY
Definition: Defines.php:74
dataWgWhitelistReadRegexp()
Provides test parameter values for testWgWhitelistReadRegexp()
Definition: TitleTest.php:382
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:925
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:1026
provideCreateFragmentTitle()
Definition: TitleTest.php:823
testLegalChars()
Title::legalChars.
Definition: TitleTest.php:33
overrideMwServices(Config $configOverrides=null, array $services=[])
Stashes the global instance of MediaWikiServices, and installs a new one, allowing test cases to over...
getInterwiki()
Get the interwiki prefix.
Definition: Title.php:912
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown...
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
static provideInvalidSecureAndSplit()
Definition: TitleTest.php:89
provideIsRawHtmlMessage()
Definition: TitleTest.php:1012
testSecureAndSplitInvalid( $text, $expectedErrorMessage)
See also mediawiki.Title.test.js Title::secureAndSplit provideInvalidSecureAndSplit.
Definition: TitleTest.php:181
hideDeprecated( $function)
Don&#39;t throw a warning if $function is deprecated and called later.
static newFromTextThrow( $text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid, rather than returning null.
Definition: Title.php:356
isValid()
Returns true if the title is valid, false if it is invalid.
Definition: Title.php:865
static provideIsAlwaysKnown()
Definition: TitleTest.php:683
testGetPrefixedText(Title $title, $expected)
Title::getPrefixedText provideGetPrefixedText.
Definition: TitleTest.php:899
testCreateFragmentTitle(Title $title, $fragment)
Title::createFragmentTarget provideCreateFragmentTitle.
Definition: TitleTest.php:836
static newFromLinkTarget(LinkTarget $linkTarget, $forceClone='')
Returns a Title given a LinkTarget.
Definition: Title.php:271
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:589
provideGetFragmentForURL()
Definition: TitleTest.php:988
testCanHaveTalkPage(Title $title, $expected)
provideCanHaveTalkPage Title::canHaveTalkPage
Definition: TitleTest.php:779
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
provideGetPrefixedDBKey()
Definition: TitleTest.php:903
static newFromDBkey( $key)
Create a new Title from a prefixed DB key.
Definition: Title.php:231
static provideGetTalkPage_bad()
Definition: TitleTest.php:804
createFragmentTarget( $fragment)
Creates a new Title for a different fragment of the same page.
Definition: Title.php:1642
provideCastFromLinkTarget()
Definition: TitleTest.php:599
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
Variant of the Message class.
Definition: RawMessage.php:34
testIsRawHtmlMessage( $textForm, $expected)
Title::isRawHtmlMessage provideIsRawHtmlMessage.
Definition: TitleTest.php:1001
provideCanHaveTalkPage()
Definition: TitleTest.php:755
static provideGetTitleValue()
Definition: TitleTest.php:620
testGetSubpageText( $title, $expected, $msg='')
Definition: TitleTest.php:536
testGetTitleValue( $text)
Title::getTitleValue provideGetTitleValue.
Definition: TitleTest.php:632
getText()
Returns the link in text form, without namespace prefix or fragment.
static provideGetTalkPage_good()
Definition: TitleTest.php:784
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:700
const NS_TALK
Definition: Defines.php:61
testGetFragment( $full, $fragment)
Title::getFragment provideGetFragment.
Definition: TitleTest.php:667
testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg='')
provideGetPageViewLanguage Title::getPageViewLanguage
Definition: TitleTest.php:431
testNewFromLinkTarget_clone()
Title::newFromLinkTarget.
Definition: TitleTest.php:589
return true to allow those checks to and false if checking is done remove or add to the links of a group of changes in EnhancedChangesList Hook subscribers can return false to omit this line from recentchanges use this to change the tables headers change it to an object instance and return false override the list derivative used the name of the old file & $article
Definition: hooks.txt:1473
testNewMainPage()
Title::newMainPage.
Definition: TitleTest.php:1117
const NS_USER_TALK
Definition: Defines.php:63
testGetTalkPageIfDefined_good(Title $title)
provideGetTalkPage_good Title::getTalkPageIfDefined
Definition: TitleTest.php:795
static newFromTitleValue(TitleValue $titleValue, $forceClone='')
Returns a Title given a TitleValue.
Definition: Title.php:256
testNewFromLinkTarget(LinkTarget $value)
Title::newFromLinkTarget provideNewFromTitleValue.
Definition: TitleTest.php:577
testCastFromLinkTarget( $value)
Title::castFromLinkTarget provideCastFromLinkTarget.
Definition: TitleTest.php:607
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1473
getPrefixedDBkey()
Get the prefixed database key form.
Definition: Title.php:1684
testNewFromTitleValue(TitleValue $value)
Title::newFromTitleValue provideNewFromTitleValue.
Definition: TitleTest.php:564
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:319